diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..24487ced6b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,36 @@ +name: Java CI with Gradle + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'temurin' + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ${{ runner.os }}-gradle- + - name: Build with Gradle + run: ./gradlew build + env: + GPR_USER: ${{ secrets.GPR_USER }} + GPR_KEY: ${{ secrets.GPR_KEY }} + - name: Archive artifacts + uses: actions/upload-artifact@v3 + with: + name: OpenComputers + path: build/libs/*.jar diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000..f68ee4d979 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,154 @@ +name: publish + +on: + release: + types: [published] + +jobs: + publish-github: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Extract Version from Tag + uses: rishabhgupta/split-by@v1 + id: split_tag + with: + string: ${{ github.event.release.tag_name }} + split-by: '/' + + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ubuntu-latest-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ubuntu-latest-gradle- + - name: Build with Gradle + run: ./gradlew -Pmod_version='${{ steps.split_tag.outputs._1 }}' build + env: + GPR_USER: ${{ secrets.GPR_USER }} + GPR_KEY: ${{ secrets.GPR_KEY }} + + - name: Add Artifacts to Github Release + uses: alexellis/upload-assets@0.3.0 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + asset_paths: '["./build/libs/*.jar"]' + + - name: Publish to Github Packages + run: ./gradlew -Pmod_version='${{ steps.split_tag.outputs._1 }}' publish + env: + GPR_USER: ${{ secrets.GPR_USER }} + GPR_KEY: ${{ secrets.GPR_KEY }} + GITHUB_MAVEN_URL: 'https://maven.pkg.github.com/${{ github.repository }}' + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + publish-curse: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Extract Version from Tag + uses: rishabhgupta/split-by@v1 + id: split_tag + with: + string: ${{ github.event.release.tag_name }} + split-by: '/' + + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ubuntu-latest-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ubuntu-latest-gradle- + + # Set Curseforge release type based on pre-release flag. + - name: Set release type to 'release' + run: | + echo "CURSEFORGE_RELEASE_TYPE=release" >> $GITHUB_ENV + if: github.event.release.prerelease == false + - name: Set release type to 'alpha' + run: | + echo "CURSEFORGE_RELEASE_TYPE=alpha" >> $GITHUB_ENV + if: github.event.release.prerelease == true + + - name: Publish to Curseforge + run: ./gradlew -Pmod_version='${{ steps.split_tag.outputs._1 }}' curseforge + env: + GPR_USER: ${{ secrets.GPR_USER }} + GPR_KEY: ${{ secrets.GPR_KEY }} + CURSEFORGE_API_KEY: ${{ secrets.CURSEFORGE_API_KEY }} + CURSEFORGE_RELEASE_TYPE: ${{ env.CURSEFORGE_RELEASE_TYPE }} + CHANGELOG: ${{ github.event.release.body }} + + publish-modrinth: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Extract Version from Tag + uses: rishabhgupta/split-by@v1 + id: split_tag + with: + string: ${{ github.event.release.tag_name }} + split-by: '/' + + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'temurin' + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ubuntu-latest-gradle-${{ hashFiles('**/*.gradle*') }} + restore-keys: ubuntu-latest-gradle- + + # Set Modrinth release type based on pre-release flag. + - name: Set release type to 'release' + run: | + echo "MODRINTH_RELEASE_TYPE=release" >> $GITHUB_ENV + if: github.event.release.prerelease == false + - name: Set release type to 'alpha' + run: | + echo "MODRINTH_RELEASE_TYPE=alpha" >> $GITHUB_ENV + if: github.event.release.prerelease == true + + - name: Publish to Modrinth + run: ./gradlew -Pmod_version='${{ steps.split_tag.outputs._1 }}' modrinth + env: + GPR_USER: ${{ secrets.GPR_USER }} + GPR_KEY: ${{ secrets.GPR_KEY }} + MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }} + MODRINTH_RELEASE_TYPE: ${{ env.MODRINTH_RELEASE_TYPE }} + CHANGELOG: ${{ github.event.release.body }} diff --git a/build.gradle b/build.gradle index 18e2e0553b..34c5061425 100644 --- a/build.gradle +++ b/build.gradle @@ -1,27 +1,23 @@ -// For those who want the bleeding edge buildscript { repositories { - jcenter() - maven { - name = "forge" - url = "https://files.minecraftforge.net/maven" - } + maven { url = 'https://maven.minecraftforge.net' } + mavenCentral() } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true } } plugins { - id "com.matthewprenger.cursegradle" version "1.0.9" + id "com.matthewprenger.cursegradle" version "1.4.0" + id 'com.modrinth.minotaur' version '2.2.0' } apply plugin: 'scala' -apply plugin: 'net.minecraftforge.gradle.forge' +apply plugin: 'net.minecraftforge.gradle' apply plugin: 'maven-publish' -sourceCompatibility = JavaVersion.VERSION_1_7 -targetCompatibility = JavaVersion.VERSION_1_7 +java.toolchain.languageVersion = JavaLanguageVersion.of(8) file "build.properties" withReader { def prop = new Properties() @@ -29,7 +25,11 @@ file "build.properties" withReader { ext.config = new ConfigSlurper().parse prop } -version = config.mod.version +version = "${mod_version}" +if (version.endsWith("-snapshot")) { + version += "-" + (new Date().format('yyyyMMdd')) +} + group = config.mod.group archivesBaseName = config.mod.name @@ -46,119 +46,162 @@ def getGitRef() { } } -if (System.getenv("PROMOTED_NUMBER") != null) - version += ".${System.getenv("PROMOTED_NUMBER")}" -else if (System.getenv("BUILD_NUMBER") != null) - version += ".${System.getenv("BUILD_NUMBER")}" -else - version += "+" + getGitRef() +version += "+" + getGitRef() ext.simpleVersion = version version = "MC${config.minecraft.version}-${project.version}" minecraft { - version = "${config.minecraft.version}-${config.forge.version}" - runDir = "run" + mappings channel: "official", version: config.minecraft.version + + accessTransformer = file("src/main/resources/META-INF/accesstransformer.cfg") - mappings = config.minecraft.mappings + runs { + client { + workingDirectory project.file("run") + property "forge.logging.markers", "REGISTRIES" + property "forge.logging.console.level", "debug" + environment "MOD_CLASSES", "opencomputers%%" + } - replace "@VERSION@", project.simpleVersion - replace "/*@MCVERSIONDEP@*/", ", acceptedMinecraftVersions = \"[${config.minecraft.version}]\"" + server { + workingDirectory project.file("run") + property "forge.logging.markers", "REGISTRIES" + property "forge.logging.console.level", "debug" + environment "MOD_CLASSES", "opencomputers%%" + } + } } repositories { - maven { url "https://maven.cil.li/" } - maven { url "https://minecraft.curseforge.com/api/maven/" } + maven { + url "https://cursemaven.com" + content { + includeGroup "curse.maven" + } + } + maven { + url "https://maven.cil.li/" + content { + includeGroup "li.cil.tis3d" + } + } + ivy { + name 'asie dependency mirror' + artifactPattern "http://asie.pl/javadeps/[module]-[revision](-[classifier]).[ext]" + content { + includeModule '', 'OC-LuaJ' + includeModule '', 'OC-JNLua' + includeModule '', 'OC-JNLua-Natives' + } + metadataSources { + artifact() + } + } + maven { + url "https://dvs1.progwml6.com/files/maven" + content { + includeGroup "mezz.jei" + } + } + maven { + url "https://chickenbones.net/maven/" + content { + includeGroup "codechicken" + includeGroup "mrtjp" + } + } + maven { + url "https://squiddev.cc/maven/" + content { + includeGroup "org.squiddev" + } + } + maven { + url "https://modmaven.dev/" + content { + includeGroup "appeng" + includeGroup "mekanism" + } + } + maven { + url "https://proxy-maven.covers1624.net/" + content { + includeModule "net.minecraftforge", "Scorge" + } + } + mavenCentral() } configurations { embedded - compile.extendsFrom provided, embedded + implementation.extendsFrom embedded +} + +task devJar(type: Jar) { + classifier = 'dev' + dependsOn(jar.dependsOn) + from(jar.source) } dependencies { - deobfCompile ("li.cil.tis3d:TIS-3D:MC1.12-${config.tis3d.version}") { - exclude module: "jei_1.12" - } - deobfCompile "com.mod-buildcraft:buildcraft-api:${config.buildcraft.version}" - deobfCompile "MCMultiPart2:MCMultiPart-exp:${config.mcmp.version}" - provided ("net.sengir.forestry:forestry_1.12.2:${config.forestry.version}") { - exclude module: "jei_1.12" - } - deobfCompile "net.industrial-craft:industrialcraft-2:${config.ic2.version}" - deobfCompile "mcp.mobius.waila:Hwyla:${config.hwyla.version}:api" - deobfCompile "dan200.computercraft:ComputerCraft:${config.cc.version}" - deobfCompile "charset:Charset:${config.charset.version}:api" - - provided ("appeng:appliedenergistics2:${config.ae2.version}:api") { + var jeiSlug = "jei-${config.minecraft.version}" + minecraft "net.minecraftforge:forge:${config.minecraft.version}-${config.forge.version}" + runtimeOnly files(devJar.archiveFile) + + compileOnly "org.scala-lang:scala-library:2.13.4" + implementation "net.minecraftforge:Scorge:${config.scorge.version}" + embedded "com.typesafe:config:1.2.1" + + compileOnly fg.deobf("li.cil.tis3d:tis3d-1.16.5-forge:${config.tis3d.version}") + compileOnly fg.deobf("curse.maven:hwyla-${config.hwyla.projectId}:${config.hwyla.fileId}") + compileOnly fg.deobf("org.squiddev:cc-tweaked-${config.minecraft.version}:${config.cct.version}") + + compileOnly ("appeng:appliedenergistics2:${config.ae2.version}:api") { transitive = false } - provided "extracells2:ExtraCells-api:${config.extracells.version}" - - provided("mekanism:Mekanism:${config.mekanism.version}:api") { + + compileOnly("mekanism:Mekanism:${config.mekanism.version}:api") { transitive = false } - provided ("codechicken:ForgeMultipart:${config.minecraft.version}-${config.forgemultipart.version}:universal") { - exclude module: "jei_1.12" + compileOnly ("codechicken:CBMultipart:${config.cbmultipart.version}:universal") { + exclude module: jeiSlug exclude module: "CodeChickenLib" } - provided ("codechicken:ChickenASM:${config.casm.version}") + compileOnly ("codechicken:ChickenASM:${config.casm.version}") - provided "mezz.jei:jei_${config.minecraft.version}:${config.jei.version}" - provided "codechicken:CodeChickenLib:${config.minecraft.version}-${config.ccl.version}:universal" - provided "codechicken:WR-CBE:${config.minecraft.version}-${config.wrcbe.version}:universal" + compileOnly "mezz.jei:${jeiSlug}:${config.jei.version}" + compileOnly "codechicken:CodeChickenLib:${config.ccl.version}:universal" - provided ("mrtjp:ProjectRed:${config.projred.version}:Base") { - exclude module: "NotEnoughItems" + compileOnly ("mrtjp:ProjectRed:${config.projred.version}:core") { exclude module: "CodeChickenLib" - exclude module: "jei_1.12" - exclude module: "ForgeMultipart" + exclude module: jeiSlug + exclude module: "CBMultipart" } - provided ("mrtjp:ProjectRed:${config.projred.version}:integration") { - exclude module: "NotEnoughItems" - exclude module: "CodeChickenLib" - exclude module: "jei_1.12" - exclude module: "ForgeMultipart" - } + embedded name: 'OC-LuaJ', version: '20220907.1', ext: 'jar' + embedded name: 'OC-JNLua', version: '20220928.1', ext: 'jar' + embedded name: 'OC-JNLua-Natives', version: '20220928.1', ext: 'jar' - provided ("mrtjp:MrTJPCore:${config.mrtjpcore.version}:universal") { - exclude module: "NotEnoughItems" - exclude module: "CodeChickenLib" - exclude module: "jei_1.12" - exclude module: "ForgeMultipart" - } - - embedded files('libs/OpenComputers-JNLua.jar', 'libs/OpenComputers-LuaJ.jar') - - testCompile "org.mockito:mockito-all:1.10.19" - - provided "codechicken:EnderStorage:${config.minecraft.version}-${config.enderstorage.version}:universal" + compileOnly "codechicken:EnderStorage:${config.enderstorage.version}:universal" } processResources { - inputs.property "version", project.simpleVersion - inputs.property "mcversion", project.minecraft.version - inputs.property "fversion", config.forge.version + def reducedScorgeVer = config.scorge.version.replaceAll(/(\d+\.\d+)(\.\d+)/, "\$1") from(sourceSets.main.resources.srcDirs) { - include 'mcmod.info' - expand 'version':project.simpleVersion, 'mcversion':project.minecraft.version, 'fversion':config.forge.version + duplicatesStrategy = "include" + include 'META-INF/mods.toml' + expand 'version':mod_version, 'mcversion':config.minecraft.version, 'sversion':reducedScorgeVer } from(sourceSets.main.resources.srcDirs) { + duplicatesStrategy = "include" include 'application.conf' filter { line -> - line.replaceAll("@VERSION@", project.simpleVersion) + line.replaceAll("@VERSION@", mod_version) } } - from(sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' - exclude 'application.conf' - } - - // Move access transformer to META-INF - rename '(.+_at.cfg)', 'META-INF/$1' } allprojects { @@ -167,16 +210,24 @@ allprojects { } } -jar { +configure([jar, devJar]) { configurations.embedded.each { dep -> from(project.zipTree(dep)) { - exclude 'META-INF', 'META-INF/**' + exclude '*', 'META-INF', 'META-INF/**' } } manifest { - attributes FMLCorePlugin: "li.cil.oc.common.launch.TransformerLoader" - attributes FMLCorePluginContainsFMLMod: "true" - attributes FMLAT: "oc_at.cfg" + attributes([ + "Specification-Title": "opencomputers", + "Specification-Vendor": "li.cil.oc", + "Specification-Version": "1", + "Implementation-Title": project.name, + "Implementation-Version": version, + "Implementation-Vendor": config.mod.group, + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), + "FMLCorePlugin": "li.cil.oc.common.launch.TransformerLoader", + "FMLCorePluginContainsFMLMod": "true" + ]) } } @@ -201,9 +252,19 @@ artifacts { archives javadocJar } +jar.finalizedBy('reobfJar') +afterEvaluate { + prepareRuns { + dependsOn(devJar) + } +} + publishing { publications { mavenJava(MavenPublication) { + groupId = project.group + artifactId = project.name + version = mod_version artifact jar artifact apiJar artifact javadocJar @@ -211,19 +272,37 @@ publishing { } repositories { maven { - url System.getenv("MAVEN_PATH") + name = "GitHubPackages" + url = System.getenv("GITHUB_MAVEN_URL") ?: "" + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } } } } curseforge { - apiKey = project.hasProperty("curseForgeApiKey") ? project.curseForgeApiKey : "" + apiKey = System.getenv('CURSEFORGE_API_KEY') ?: "" project { id = config.curse.project.id - releaseType = config.curse.project.releaseType + releaseType = System.getenv('CURSEFORGE_RELEASE_TYPE') ?: "alpha" changelogType = "markdown" - changelog = file("changelog.md") + changelog = System.getenv("CHANGELOG") ?: "Changelog not available." addGameVersion config.minecraft.version addGameVersion "Java 8" + addGameVersion "Forge" } } + +modrinth { + token = System.getenv("MODRINTH_API_KEY") ?: "" + projectId = config.modrinth.project.id + changelog = System.getenv("CHANGELOG") ?: "Changelog not available." + versionNumber = mod_version + versionName = "${rootProject.name}-${version}" + versionType = System.getenv('MODRINTH_RELEASE_TYPE') ?: "alpha" + uploadFile = jar + gameVersions = [config.minecraft.version] + loaders = ["forge"] +} diff --git a/build.properties b/build.properties index 790da7a9ff..eba6e7cdf6 100644 --- a/build.properties +++ b/build.properties @@ -1,30 +1,23 @@ -minecraft.version=1.12.2 -minecraft.mappings=snapshot_20180704 -forge.version=14.23.5.2778 +minecraft.version=1.16.5 +forge.version=36.2.34 +scorge.version=3.1.3 mod.name=OpenComputers mod.group=li.cil.oc mod.version=1.7.5 -ae2.version=rv6-stable-5 -buildcraft.version=7.99.17 -cc.version=1.80pr1-build0 -charset.version=0.5.6.2 -extracells.version=1.12.2:2.5.3a25 -forestry.version=5.8.0.311 -hwyla.version=1.8.26-B41_1.12.2 -ic2.version=2.8.91-ex112 -jei.version=4.15.0.268 -mcmp.version=2.5.1_66 -mekanism.version=1.12.2-9.4.3.330 -tis3d.version=1.3.1.18 -projred.version=1.12.2-4.9.3.118 -mrtjpcore.version=1.12.2-2.1.4.43 -ccl.version=3.2.3.358 -forgemultipart.version=2.6.2.83 -casm.version=1.12-1.0.2.7 -enderstorage.version=2.4.5.135 -wrcbe.version=2.3.2.33 +ae2.version=8.4.7 +cct.version=1.100.5 +hwyla.projectId=253449 +hwyla.fileId=3033595 +jei.version=7.7.1.152 +mekanism.version=1.16.5-10.1.2.457 +tis3d.version=1.6.8+30 +projred.version=1.16.5-4.12.0-beta-0 +ccl.version=1.16.5-4.0.7.445 +cbmultipart.version=1.16.5-3.0.4.123 +casm.version=2.0.1.14 +enderstorage.version=1.16.5-2.8.0.170 curse.project.id=223008 -curse.project.releaseType=release +modrinth.project.id=YiAbZis2 diff --git a/gradle.properties b/gradle.properties index e69de29bb2..ee9da0b886 100644 --- a/gradle.properties +++ b/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.daemon=false +mod_version=1.8.0-snapshot diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 758de960ec..e708b1c023 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2d80b69a76..2e6e5897b5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d517..4f906e0c81 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -66,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -109,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -138,19 +156,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index e95643d6a2..ac1b06f938 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/libs/OpenComputers-JNLua.jar b/libs/OpenComputers-JNLua.jar deleted file mode 100644 index f06a8f722a..0000000000 Binary files a/libs/OpenComputers-JNLua.jar and /dev/null differ diff --git a/libs/OpenComputers-LuaJ.jar b/libs/OpenComputers-LuaJ.jar deleted file mode 100644 index 1d2cc019b4..0000000000 Binary files a/libs/OpenComputers-LuaJ.jar and /dev/null differ diff --git a/libs/factorization-api.zip b/libs/factorization-api.zip deleted file mode 100644 index 44566c78ce..0000000000 Binary files a/libs/factorization-api.zip and /dev/null differ diff --git a/libs/ic2classic-api.zip b/libs/ic2classic-api.zip deleted file mode 100644 index 5025bac68f..0000000000 Binary files a/libs/ic2classic-api.zip and /dev/null differ diff --git a/src/main/java/li/cil/oc/api/CreativeTab.java b/src/main/java/li/cil/oc/api/CreativeTab.java index 2454256fe3..219309b60f 100644 --- a/src/main/java/li/cil/oc/api/CreativeTab.java +++ b/src/main/java/li/cil/oc/api/CreativeTab.java @@ -1,6 +1,6 @@ package li.cil.oc.api; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.ItemGroup; /** * Allows access to the creative tab used by OpenComputers. @@ -13,7 +13,7 @@ public final class CreativeTab { * not try to access this anyway when OpenComputers isn't * present (don't ship the API in your mod), so don't rely on this! */ - public static CreativeTabs instance = CreativeTabs.REDSTONE; + public static ItemGroup instance = ItemGroup.TAB_REDSTONE; private CreativeTab() { } diff --git a/src/main/java/li/cil/oc/api/Driver.java b/src/main/java/li/cil/oc/api/Driver.java index 4d8fe319cf..90ceb83bd9 100644 --- a/src/main/java/li/cil/oc/api/Driver.java +++ b/src/main/java/li/cil/oc/api/Driver.java @@ -6,9 +6,9 @@ import li.cil.oc.api.driver.DriverItem; import li.cil.oc.api.driver.DriverBlock; import li.cil.oc.api.network.EnvironmentHost; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; @@ -124,7 +124,7 @@ public static void add(final InventoryProvider provider) { * @param pos the position of the block. * @return a driver for the block, or null if there is none. */ - public static DriverBlock driverFor(World world, BlockPos pos, EnumFacing side) { + public static DriverBlock driverFor(World world, BlockPos pos, Direction side) { if (API.driver != null) return API.driver.driverFor(world, pos, side); return null; @@ -214,7 +214,7 @@ public static Set> environmentsFor(ItemStack stack) { * @param player the player holding the item. May be null. * @return the IItemHandler implementation interfacing the stack, or null. */ - public static IItemHandler itemHandlerFor(ItemStack stack, EntityPlayer player) { + public static IItemHandler itemHandlerFor(ItemStack stack, PlayerEntity player) { if (API.driver != null) return API.driver.itemHandlerFor(stack, player); return null; diff --git a/src/main/java/li/cil/oc/api/FileSystem.java b/src/main/java/li/cil/oc/api/FileSystem.java index 49557d0cf5..4dfc83344a 100644 --- a/src/main/java/li/cil/oc/api/FileSystem.java +++ b/src/main/java/li/cil/oc/api/FileSystem.java @@ -3,6 +3,7 @@ import li.cil.oc.api.network.EnvironmentHost; import li.cil.oc.api.fs.Label; import li.cil.oc.api.network.ManagedEnvironment; +import net.minecraft.util.ResourceLocation; /** * This class provides factory methods for creating file systems that are @@ -22,29 +23,25 @@ */ public final class FileSystem { /** - * Creates a new file system based on the location of a class. + * Creates a new file system based on a mod-specific resource location where + * the namespace refers to the mod and the resource path denotes a + * (mandatory) subpath relative to that mod's assets directory. *

- * This can be used to wrap a folder in the assets folder of your mod's JAR. - * The actual path is built like this: - *

"/assets/" + domain + "/" + root
- *

- * If the class is located in a JAR file, this will create a read-only file - * system based on that JAR file. If the class file is located in the native - * file system, this will create a read-only file system first trying from - * the actual location of the class file, and failing that by searching the - * class path (i.e. it'll look for a path constructed as described above). + * If {@code location} is stored in a JAR file, this will create a read-only + * file system based on that JAR file. If {@code location} is stored in the + * native file system, this will create a read-only file system from the the + * location constructed as described above (relative to the root of the + * namespace). *

* If the specified path cannot be located, the creation fails and this * returns null. * - * @param clazz the class whose containing JAR to wrap. - * @param domain the domain, usually your mod's ID. - * @param root an optional subdirectory. - * @return a file system wrapping the specified folder. + * @param location the location where the file system's contents are stored. + * @return a file system wrapping the specified resource. */ - public static li.cil.oc.api.fs.FileSystem fromClass(final Class clazz, final String domain, final String root) { + public static li.cil.oc.api.fs.FileSystem fromResource(final ResourceLocation location) { if (API.fileSystem != null) - return API.fileSystem.fromClass(clazz, domain, root); + return API.fileSystem.fromResource(location); return null; } diff --git a/src/main/java/li/cil/oc/api/IMC.java b/src/main/java/li/cil/oc/api/IMC.java index 6149544096..11f286e162 100644 --- a/src/main/java/li/cil/oc/api/IMC.java +++ b/src/main/java/li/cil/oc/api/IMC.java @@ -1,10 +1,10 @@ package li.cil.oc.api; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; -import net.minecraftforge.fml.common.event.FMLInterModComms; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.nbt.StringNBT; +import net.minecraftforge.fml.InterModComms; import org.apache.commons.lang3.tuple.Pair; /** @@ -53,7 +53,7 @@ public final class IMC { * @param callback the callback to register as a filtering method. */ public static void registerAssemblerFilter(final String callback) { - FMLInterModComms.sendMessage(MOD_ID, REGISTER_ASSEMBLER_FILTER, callback); + InterModComms.sendTo(MOD_ID, REGISTER_ASSEMBLER_FILTER, () -> callback); } /** @@ -114,59 +114,59 @@ public static void registerAssemblerFilter(final String callback) { * for the third component slot. Up to nine. */ public static void registerAssemblerTemplate(final String name, final String select, final String validate, final String assemble, final Class host, final int[] containerTiers, final int[] upgradeTiers, final Iterable> componentSlots) { - final NBTTagCompound nbt = new NBTTagCompound(); + final CompoundNBT nbt = new CompoundNBT(); if (name != null) { - nbt.setString("name", name); + nbt.putString("name", name); } - nbt.setString("select", select); - nbt.setString("validate", validate); - nbt.setString("assemble", assemble); + nbt.putString("select", select); + nbt.putString("validate", validate); + nbt.putString("assemble", assemble); if (host != null) { - nbt.setString("hostClass", host.getName()); + nbt.putString("hostClass", host.getName()); } - final NBTTagList containersNbt = new NBTTagList(); + final ListNBT containersNbt = new ListNBT(); if (containerTiers != null) { for (int tier : containerTiers) { - final NBTTagCompound slotNbt = new NBTTagCompound(); - slotNbt.setInteger("tier", tier); - containersNbt.appendTag(slotNbt); + final CompoundNBT slotNbt = new CompoundNBT(); + slotNbt.putInt("tier", tier); + containersNbt.add(slotNbt); } } - if (containersNbt.tagCount() > 0) { - nbt.setTag("containerSlots", containersNbt); + if (containersNbt.size() > 0) { + nbt.put("containerSlots", containersNbt); } - final NBTTagList upgradesNbt = new NBTTagList(); + final ListNBT upgradesNbt = new ListNBT(); if (upgradeTiers != null) { for (int tier : upgradeTiers) { - final NBTTagCompound slotNbt = new NBTTagCompound(); - slotNbt.setInteger("tier", tier); - upgradesNbt.appendTag(slotNbt); + final CompoundNBT slotNbt = new CompoundNBT(); + slotNbt.putInt("tier", tier); + upgradesNbt.add(slotNbt); } } - if (upgradesNbt.tagCount() > 0) { - nbt.setTag("upgradeSlots", upgradesNbt); + if (upgradesNbt.size() > 0) { + nbt.put("upgradeSlots", upgradesNbt); } - final NBTTagList componentsNbt = new NBTTagList(); + final ListNBT componentsNbt = new ListNBT(); if (componentSlots != null) { for (Pair slot : componentSlots) { if (slot == null) { - componentsNbt.appendTag(new NBTTagCompound()); + componentsNbt.add(new CompoundNBT()); } else { - final NBTTagCompound slotNbt = new NBTTagCompound(); - slotNbt.setString("type", slot.getLeft()); - slotNbt.setInteger("tier", slot.getRight()); - componentsNbt.appendTag(slotNbt); + final CompoundNBT slotNbt = new CompoundNBT(); + slotNbt.putString("type", slot.getLeft()); + slotNbt.putInt("tier", slot.getRight()); + componentsNbt.add(slotNbt); } } } - if (componentsNbt.tagCount() > 0) { - nbt.setTag("componentSlots", componentsNbt); + if (componentsNbt.size() > 0) { + nbt.put("componentSlots", componentsNbt); } - FMLInterModComms.sendMessage(MOD_ID, REGISTER_ASSEMBLER_TEMPLATE, nbt); + InterModComms.sendTo(MOD_ID, REGISTER_ASSEMBLER_TEMPLATE, () -> nbt); } /** @@ -203,14 +203,14 @@ public static void registerAssemblerTemplate(final String name, final String sel * ingredients from an item. */ public static void registerDisassemblerTemplate(final String name, final String select, final String disassemble) { - final NBTTagCompound nbt = new NBTTagCompound(); + final CompoundNBT nbt = new CompoundNBT(); if (name != null) { - nbt.setString("name", name); + nbt.putString("name", name); } - nbt.setString("select", select); - nbt.setString("disassemble", disassemble); + nbt.putString("select", select); + nbt.putString("disassemble", disassemble); - FMLInterModComms.sendMessage(MOD_ID, REGISTER_DISASSEMBLER_TEMPLATE, nbt); + InterModComms.sendTo(MOD_ID, REGISTER_DISASSEMBLER_TEMPLATE, () -> nbt); } /** @@ -234,7 +234,7 @@ public static void registerDisassemblerTemplate(final String name, final String * @param callback the callback to register as a durability provider. */ public static void registerToolDurabilityProvider(final String callback) { - FMLInterModComms.sendMessage(MOD_ID, REGISTER_TOOL_DURABILITY_PROVIDER, callback); + InterModComms.sendTo(MOD_ID, REGISTER_TOOL_DURABILITY_PROVIDER, () -> callback); } /** @@ -249,7 +249,7 @@ public static void registerToolDurabilityProvider(final String callback) { *

* Signature of callbacks must be: *

-     * boolean callback(EntityPlayer player, BlockPos pos, boolean changeDurability)
+     * boolean callback(PlayerEntity player, BlockPos pos, boolean changeDurability)
      * 
*

* Callbacks must be declared as packagePath.className.methodName. @@ -258,7 +258,7 @@ public static void registerToolDurabilityProvider(final String callback) { * @param callback the callback to register as a wrench tool handler. */ public static void registerWrenchTool(final String callback) { - FMLInterModComms.sendMessage(MOD_ID, REGISTER_WRENCH_TOOL, callback); + InterModComms.sendTo(MOD_ID, REGISTER_WRENCH_TOOL, () -> callback); } /** @@ -281,7 +281,7 @@ public static void registerWrenchTool(final String callback) { * @param callback the callback to register as a wrench tool tester. */ public static void registerWrenchToolCheck(final String callback) { - FMLInterModComms.sendMessage(MOD_ID, REGISTER_WRENCH_TOOL_CHECK, callback); + InterModComms.sendTo(MOD_ID, REGISTER_WRENCH_TOOL_CHECK, () -> callback); } /** @@ -307,11 +307,11 @@ public static void registerWrenchToolCheck(final String callback) { * @param charge the callback to register for charging items. */ public static void registerItemCharge(final String name, final String canCharge, final String charge) { - final NBTTagCompound nbt = new NBTTagCompound(); - nbt.setString("name", name); - nbt.setString("canCharge", canCharge); - nbt.setString("charge", charge); - FMLInterModComms.sendMessage(MOD_ID, REGISTER_ITEM_CHARGE, nbt); + final CompoundNBT nbt = new CompoundNBT(); + nbt.putString("name", name); + nbt.putString("canCharge", canCharge); + nbt.putString("charge", charge); + InterModComms.sendTo(MOD_ID, REGISTER_ITEM_CHARGE, () -> nbt); } /** @@ -335,7 +335,7 @@ public static void registerItemCharge(final String name, final String canCharge, * @param callback the callback to register as an ink provider. */ public static void registerInkProvider(final String callback) { - FMLInterModComms.sendMessage(MOD_ID, REGISTER_INK_PROVIDER, callback); + InterModComms.sendTo(MOD_ID, REGISTER_INK_PROVIDER, () -> callback); } /** @@ -348,7 +348,7 @@ public static void registerInkProvider(final String callback) { * @param peripheral the class of the peripheral to blacklist. */ public static void blacklistPeripheral(final Class peripheral) { - FMLInterModComms.sendMessage(MOD_ID, BLACKLIST_PERIPHERAL, peripheral.getName()); + InterModComms.sendTo(MOD_ID, BLACKLIST_PERIPHERAL, () -> peripheral.getName()); } /** @@ -367,13 +367,13 @@ public static void blacklistPeripheral(final Class peripheral) { * @param stack the item stack representing the blacklisted component. */ public static void blacklistHost(final String name, final Class host, final ItemStack stack) { - final NBTTagCompound nbt = new NBTTagCompound(); - nbt.setString("name", name); - nbt.setString("host", host.getName()); - final NBTTagCompound stackNbt = new NBTTagCompound(); - stack.writeToNBT(stackNbt); - nbt.setTag("item", stackNbt); - FMLInterModComms.sendMessage(MOD_ID, BLACKLIST_HOST, nbt); + final CompoundNBT nbt = new CompoundNBT(); + nbt.putString("name", name); + nbt.putString("host", host.getName()); + final CompoundNBT stackNbt = new CompoundNBT(); + stack.save(stackNbt); + nbt.put("item", stackNbt); + InterModComms.sendTo(MOD_ID, BLACKLIST_HOST, () -> nbt); } /** @@ -401,17 +401,17 @@ public static void blacklistHost(final String name, final Class host, final Item * @param architectures the names of the architectures this entry applies to. */ public static void registerProgramDiskLabel(final String programName, final String diskLabel, final String... architectures) { - final NBTTagCompound nbt = new NBTTagCompound(); - nbt.setString("program", programName); - nbt.setString("label", diskLabel); + final CompoundNBT nbt = new CompoundNBT(); + nbt.putString("program", programName); + nbt.putString("label", diskLabel); if (architectures != null && architectures.length > 0) { - final NBTTagList architecturesNbt = new NBTTagList(); + final ListNBT architecturesNbt = new ListNBT(); for (final String architecture : architectures) { - architecturesNbt.appendTag(new NBTTagString(architecture)); + architecturesNbt.add(StringNBT.valueOf(architecture)); } - nbt.setTag("architectures", architecturesNbt); + nbt.put("architectures", architecturesNbt); } - FMLInterModComms.sendMessage(MOD_ID, REGISTER_PROGRAM_DISK_LABEL, nbt); + InterModComms.sendTo(MOD_ID, REGISTER_PROGRAM_DISK_LABEL, () -> nbt); } // ----------------------------------------------------------------------- // diff --git a/src/main/java/li/cil/oc/api/Items.java b/src/main/java/li/cil/oc/api/Items.java index ec37582994..b9e7d86903 100644 --- a/src/main/java/li/cil/oc/api/Items.java +++ b/src/main/java/li/cil/oc/api/Items.java @@ -1,8 +1,9 @@ package li.cil.oc.api; import li.cil.oc.api.detail.ItemInfo; -import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.DyeColor; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import java.util.concurrent.Callable; @@ -54,11 +55,11 @@ public static ItemInfo get(ItemStack stack) { *

* The specified factory callable will be used to generate a new file * system when the loot disk is used as a component. The specified name - * will be used as the label for the loot disk, as well as the identifier - * to select the corresponding factory method, so choose wisely. + * will be used as the label for the loot disk, while the location serves + * as the identifier to select the corresponding factory method. *

* To use some directory in your mod JAR as the directory provided by the - * loot disk, use {@link FileSystem#fromClass} in your callable. + * loot disk, use {@link FileSystem#fromResource} in your callable. *

* If doRecipeCycling is true, the floppy disk will be * included in the floppy disk recipe cycle if that is enabled. @@ -66,15 +67,18 @@ public static ItemInfo get(ItemStack stack) { * Call this in the init phase or later, not in pre-init. * * @param name the label and identifier to use for the loot disk. + * @param loc the location where the disk's contents are stored. * @param color the color of the disk, as a Minecraft color. * @param factory the callable to call for creating file system instances. * @param doRecipeCycling whether to include this floppy disk in floppy disk cycling. * @return an item stack representing the registered loot disk, to allow * adding a recipe for your loot disk, for example. */ - public static ItemStack registerFloppy(String name, EnumDyeColor color, Callable factory, boolean doRecipeCycling) { + public static ItemStack registerFloppy(String name, ResourceLocation loc, DyeColor color, + Callable factory, boolean doRecipeCycling) { + if (API.items != null) - return API.items.registerFloppy(name, color, factory, doRecipeCycling); + return API.items.registerFloppy(name, loc, color, factory, doRecipeCycling); return ItemStack.EMPTY; } diff --git a/src/main/java/li/cil/oc/api/Manual.java b/src/main/java/li/cil/oc/api/Manual.java index 5096202c78..90b6af2d70 100644 --- a/src/main/java/li/cil/oc/api/Manual.java +++ b/src/main/java/li/cil/oc/api/Manual.java @@ -5,7 +5,7 @@ import li.cil.oc.api.manual.ImageRenderer; import li.cil.oc.api.manual.PathProvider; import li.cil.oc.api.manual.TabIconRenderer; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -153,7 +153,7 @@ public static Iterable contentFor(String path) { * * @param player the player to open the manual for. */ - public static void openFor(EntityPlayer player) { + public static void openFor(PlayerEntity player) { if (API.manual != null) API.manual.openFor(player); } diff --git a/src/main/java/li/cil/oc/api/Nanomachines.java b/src/main/java/li/cil/oc/api/Nanomachines.java index afa239b8d4..39a18df84d 100644 --- a/src/main/java/li/cil/oc/api/Nanomachines.java +++ b/src/main/java/li/cil/oc/api/Nanomachines.java @@ -2,7 +2,7 @@ import li.cil.oc.api.nanomachines.BehaviorProvider; import li.cil.oc.api.nanomachines.Controller; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import java.util.Collections; @@ -44,7 +44,7 @@ public static Iterable getProviders() { * @param player the player to check for. * @return true if the player has a controller, false otherwise. */ - public static boolean hasController(EntityPlayer player) { + public static boolean hasController(PlayerEntity player) { if (API.nanomachines != null) return API.nanomachines.hasController(player); return false; @@ -60,7 +60,7 @@ public static boolean hasController(EntityPlayer player) { * @param player the player to get the controller for. * @return the controller for the specified player. */ - public static Controller getController(EntityPlayer player) { + public static Controller getController(PlayerEntity player) { if (API.nanomachines != null) return API.nanomachines.getController(player); return null; @@ -75,7 +75,7 @@ public static Controller getController(EntityPlayer player) { * * @param player the player to install a nanomachine controller for. */ - public static Controller installController(EntityPlayer player) { + public static Controller installController(PlayerEntity player) { if (API.nanomachines != null) return API.nanomachines.installController(player); return null; @@ -88,7 +88,7 @@ public static Controller installController(EntityPlayer player) { * * @param player the player to uninstall a nanomachine controller from. */ - public static void uninstallController(EntityPlayer player) { + public static void uninstallController(PlayerEntity player) { if (API.nanomachines != null) API.nanomachines.uninstallController(player); } diff --git a/src/main/java/li/cil/oc/api/Network.java b/src/main/java/li/cil/oc/api/Network.java index 5db80f8e5c..f306f68560 100644 --- a/src/main/java/li/cil/oc/api/Network.java +++ b/src/main/java/li/cil/oc/api/Network.java @@ -6,10 +6,12 @@ import li.cil.oc.api.network.Packet; import li.cil.oc.api.network.Visibility; import li.cil.oc.api.network.WirelessEndpoint; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.RegistryKey; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; /** * This class provides factories for networks and nodes. @@ -31,7 +33,7 @@ */ public final class Network { /** - * Convenience overload for {@link #joinOrCreateNetwork(IBlockAccess, BlockPos)}. + * Convenience overload for {@link #joinOrCreateNetwork(IBlockReader, BlockPos)}. *

* If the tile entity implements {@link Environment} its one node will be * connected to any existing adjacent tile entity nodes. If none exist a @@ -56,7 +58,7 @@ public static void joinOrCreateNetwork(final TileEntity tileEntity) { * @param world the world containing the location to connect. * @param pos the position at which to update the network. */ - public static void joinOrCreateNetwork(final IBlockAccess world, final BlockPos pos) { + public static void joinOrCreateNetwork(final IBlockReader world, final BlockPos pos) { if (API.network != null) API.network.joinOrCreateNetwork(world, pos); } @@ -138,7 +140,7 @@ public static void leaveWirelessNetwork(final WirelessEndpoint endpoint) { * @param endpoint the endpoint to remove from the wireless network. * @param dimension the dimension with the wireless network to remove the endpoint from. */ - public static void leaveWirelessNetwork(final WirelessEndpoint endpoint, final int dimension) { + public static void leaveWirelessNetwork(final WirelessEndpoint endpoint, final RegistryKey dimension) { if (API.network != null) API.network.leaveWirelessNetwork(endpoint, dimension); } @@ -233,7 +235,7 @@ public static Packet newPacket(final String source, final String destination, fi * @param nbt the tag to load the packet from. * @return the loaded packet. */ - public static Packet newPacket(final NBTTagCompound nbt) { + public static Packet newPacket(final CompoundNBT nbt) { if (API.network != null) return API.network.newPacket(nbt); return null; diff --git a/src/main/java/li/cil/oc/api/Persistable.java b/src/main/java/li/cil/oc/api/Persistable.java index 8ad2b2a459..b7bb1ccf93 100644 --- a/src/main/java/li/cil/oc/api/Persistable.java +++ b/src/main/java/li/cil/oc/api/Persistable.java @@ -1,6 +1,6 @@ package li.cil.oc.api; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; /** * An object that can be persisted to an NBT tag and restored back from it. @@ -11,15 +11,15 @@ public interface Persistable { * * @param nbt the tag to read the state from. */ - void load(NBTTagCompound nbt); + void loadData(CompoundNBT nbt); /** * Saves the current state of the object into the specified NBT tag. *

* This should write the state in such a way that it can be restored when - * {@link #load} is called with that tag. + * {@link #loadData} is called with that tag. * * @param nbt the tag to save the state to. */ - void save(NBTTagCompound nbt); + void saveData(CompoundNBT nbt); } \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/component/RackMountable.java b/src/main/java/li/cil/oc/api/component/RackMountable.java index efe4057441..9c4aecce41 100644 --- a/src/main/java/li/cil/oc/api/component/RackMountable.java +++ b/src/main/java/li/cil/oc/api/component/RackMountable.java @@ -4,11 +4,11 @@ import li.cil.oc.api.network.ComponentHost; import li.cil.oc.api.network.ManagedEnvironment; import li.cil.oc.api.util.StateAware; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumHand; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.Hand; /** * Use this interface on environments provided by drivers for items that can @@ -41,7 +41,7 @@ public interface RackMountable extends ManagedEnvironment, StateAware { * * @return the data to synchronize to the clients. */ - NBTTagCompound getData(); + CompoundNBT getData(); /** * The number of connectables exposed by the environment. @@ -70,5 +70,5 @@ public interface RackMountable extends ManagedEnvironment, StateAware { * @param hitY the relative y coordinate of the activation on the mountable. * @return whether the activation was handled (e.g. GUI opened). */ - boolean onActivate(EntityPlayer player, EnumHand hand, ItemStack heldItem, float hitX, float hitY); + boolean onActivate(PlayerEntity player, Hand hand, ItemStack heldItem, float hitX, float hitY); } diff --git a/src/main/java/li/cil/oc/api/component/package-info.java b/src/main/java/li/cil/oc/api/component/package-info.java index b8dc74b7bc..e4fee4451b 100644 --- a/src/main/java/li/cil/oc/api/component/package-info.java +++ b/src/main/java/li/cil/oc/api/component/package-info.java @@ -4,10 +4,6 @@ * This will allow OpenComputers to provide some more advanced integration * with your components. */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|component", - apiVersion = API.VERSION) package li.cil.oc.api.component; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/detail/DriverAPI.java b/src/main/java/li/cil/oc/api/detail/DriverAPI.java index 138f60becb..c0bcd02681 100644 --- a/src/main/java/li/cil/oc/api/detail/DriverAPI.java +++ b/src/main/java/li/cil/oc/api/detail/DriverAPI.java @@ -6,9 +6,9 @@ import li.cil.oc.api.driver.DriverItem; import li.cil.oc.api.driver.DriverBlock; import li.cil.oc.api.network.EnvironmentHost; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; @@ -95,7 +95,7 @@ public interface DriverAPI { * @return a driver for the block, or null if there is none. */ @Nullable - DriverBlock driverFor(World world, BlockPos pos, EnumFacing side); + DriverBlock driverFor(World world, BlockPos pos, Direction side); /** * Looks up a driver for the specified item stack. @@ -167,7 +167,7 @@ public interface DriverAPI { * @param player the player holding the item. May be null. * @return the IItemHandler implementation interfacing the stack, or null. */ - IItemHandler itemHandlerFor(ItemStack stack, EntityPlayer player); + IItemHandler itemHandlerFor(ItemStack stack, PlayerEntity player); /** * Get a list of all registered item drivers. diff --git a/src/main/java/li/cil/oc/api/detail/FileSystemAPI.java b/src/main/java/li/cil/oc/api/detail/FileSystemAPI.java index fa58c3b1a6..6f37e77ee8 100644 --- a/src/main/java/li/cil/oc/api/detail/FileSystemAPI.java +++ b/src/main/java/li/cil/oc/api/detail/FileSystemAPI.java @@ -4,30 +4,27 @@ import li.cil.oc.api.fs.FileSystem; import li.cil.oc.api.fs.Label; import li.cil.oc.api.network.ManagedEnvironment; +import net.minecraft.util.ResourceLocation; public interface FileSystemAPI { /** - * Creates a new file system based on the location of a class. + * Creates a new file system based on a mod-specific resource location where + * the namespace refers to the mod and the resource path denotes a + * (mandatory) subpath relative to that mod's assets directory. *

- * This can be used to wrap a folder in the assets folder of your mod's JAR. - * The actual path is built like this: - *

"/assets/" + domain + "/" + root
- *

- * If the class is located in a JAR file, this will create a read-only file - * system based on that JAR file. If the class file is located in the native - * file system, this will create a read-only file system first trying from - * the actual location of the class file, and failing that by searching the - * class path (i.e. it'll look for a path constructed as described above). + * If {@code location} is stored in a JAR file, this will create a read-only + * file system based on that JAR file. If {@code location} is stored in the + * native file system, this will create a read-only file system from the the + * location constructed as described above (relative to the root of the + * namespace). *

* If the specified path cannot be located, the creation fails and this * returns null. * - * @param clazz the class whose containing JAR to wrap. - * @param domain the domain, usually your mod's ID. - * @param root an optional subdirectory. - * @return a file system wrapping the specified folder. + * @param location the location where the file system's contents are stored. + * @return a file system wrapping the specified resource. */ - FileSystem fromClass(Class clazz, String domain, String root); + FileSystem fromResource(ResourceLocation location); /** * Creates a new writable file system in the save folder. diff --git a/src/main/java/li/cil/oc/api/detail/ItemAPI.java b/src/main/java/li/cil/oc/api/detail/ItemAPI.java index 579500cf5b..f29c54230c 100644 --- a/src/main/java/li/cil/oc/api/detail/ItemAPI.java +++ b/src/main/java/li/cil/oc/api/detail/ItemAPI.java @@ -1,8 +1,9 @@ package li.cil.oc.api.detail; import li.cil.oc.api.FileSystem; -import net.minecraft.item.EnumDyeColor; +import net.minecraft.item.DyeColor; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import javax.annotation.Nullable; import java.util.concurrent.Callable; @@ -41,11 +42,11 @@ public interface ItemAPI { *

* The specified factory callable will be used to generate a new file * system when the loot disk is used as a component. The specified name - * will be used as the label for the loot disk, as well as the identifier - * to select the corresponding factory method, so choose wisely. + * will be used as the label for the loot disk, while the location serves + * as the identifier to select the corresponding factory method. *

* To use some directory in your mod JAR as the directory provided by the - * loot disk, use {@link FileSystem#fromClass} in your callable. + * loot disk, use {@link FileSystem#fromResource} in your callable. *

* If doRecipeCycling is true, the floppy disk will be * included in the floppy disk recipe cycle if that is enabled. @@ -53,13 +54,15 @@ public interface ItemAPI { * Call this in the init phase or later, not in pre-init. * * @param name the label and identifier to use for the loot disk. + * @param loc the location where the disk's contents are stored. * @param color the color of the disk, as a Minecraft color. * @param factory the callable to call for creating file system instances. * @param doRecipeCycling whether to include this floppy disk in floppy disk cycling. * @return an item stack representing the registered loot disk, to allow * adding a recipe for your loot disk, for example. */ - ItemStack registerFloppy(String name, EnumDyeColor color, Callable factory, boolean doRecipeCycling); + ItemStack registerFloppy(String name, ResourceLocation loc, DyeColor color, + Callable factory, boolean doRecipeCycling); /** * Register a single custom EEPROM. diff --git a/src/main/java/li/cil/oc/api/detail/ManualAPI.java b/src/main/java/li/cil/oc/api/detail/ManualAPI.java index 605955472d..0eb9718bcc 100644 --- a/src/main/java/li/cil/oc/api/detail/ManualAPI.java +++ b/src/main/java/li/cil/oc/api/detail/ManualAPI.java @@ -5,7 +5,7 @@ import li.cil.oc.api.manual.ImageRenderer; import li.cil.oc.api.manual.PathProvider; import li.cil.oc.api.manual.TabIconRenderer; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -90,7 +90,7 @@ public interface ManualAPI { *

* The provided path may contain the special variable %LANGUAGE%, * which will be resolved to the currently set language, falling back to - * en_US. + * en_us. * * @param path the path of the page to get the content of. * @return the content of the page, or null if none exists. @@ -119,7 +119,7 @@ public interface ManualAPI { * * @param player the player to open the manual for. */ - void openFor(EntityPlayer player); + void openFor(PlayerEntity player); /** * Reset the history of the manual. diff --git a/src/main/java/li/cil/oc/api/detail/NanomachinesAPI.java b/src/main/java/li/cil/oc/api/detail/NanomachinesAPI.java index 4a85f5fcf7..3459c3e86c 100644 --- a/src/main/java/li/cil/oc/api/detail/NanomachinesAPI.java +++ b/src/main/java/li/cil/oc/api/detail/NanomachinesAPI.java @@ -2,7 +2,7 @@ import li.cil.oc.api.nanomachines.BehaviorProvider; import li.cil.oc.api.nanomachines.Controller; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; public interface NanomachinesAPI { /** @@ -29,7 +29,7 @@ public interface NanomachinesAPI { * @param player the player to check for. * @return true if the player has a controller, false otherwise. */ - boolean hasController(EntityPlayer player); + boolean hasController(PlayerEntity player); /** * Get the nanomachine controller of the specified player. @@ -41,7 +41,7 @@ public interface NanomachinesAPI { * @param player the player to get the controller for. * @return the controller for the specified player. */ - Controller getController(EntityPlayer player); + Controller getController(PlayerEntity player); /** * Install a controller for the specified player if it doesn't already @@ -53,7 +53,7 @@ public interface NanomachinesAPI { * @param player the player to install a nanomachine controller for. * @return the controller for the specified player. */ - Controller installController(EntityPlayer player); + Controller installController(PlayerEntity player); /** * Uninstall a controller from the specified player if it has one. @@ -62,5 +62,5 @@ public interface NanomachinesAPI { * * @param player the player to uninstall a nanomachine controller from. */ - void uninstallController(EntityPlayer player); + void uninstallController(PlayerEntity player); } diff --git a/src/main/java/li/cil/oc/api/detail/NetworkAPI.java b/src/main/java/li/cil/oc/api/detail/NetworkAPI.java index 967f4f1fd1..b48d129989 100644 --- a/src/main/java/li/cil/oc/api/detail/NetworkAPI.java +++ b/src/main/java/li/cil/oc/api/detail/NetworkAPI.java @@ -5,14 +5,16 @@ import li.cil.oc.api.network.Packet; import li.cil.oc.api.network.Visibility; import li.cil.oc.api.network.WirelessEndpoint; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.RegistryKey; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; public interface NetworkAPI { /** - * Convenience overload for {@link #joinOrCreateNetwork(IBlockAccess, BlockPos)}. + * Convenience overload for {@link #joinOrCreateNetwork(IBlockReader, BlockPos)}. *

* If the tile entity implements {@link Environment} its one node will be * connected to any existing adjacent tile entity nodes. If none exist a @@ -34,7 +36,7 @@ public interface NetworkAPI { * @param world the world containing the location to connect. * @param pos the position at which to update the network. */ - void joinOrCreateNetwork(IBlockAccess world, BlockPos pos); + void joinOrCreateNetwork(IBlockReader world, BlockPos pos); /** * Creates a new network with the specified node as its initial node. @@ -101,7 +103,7 @@ public interface NetworkAPI { * @param endpoint the endpoint to remove from the wireless network. * @param dimension the dimension with the wireless network to remove the endpoint from. */ - void leaveWirelessNetwork(WirelessEndpoint endpoint, int dimension); + void leaveWirelessNetwork(WirelessEndpoint endpoint, RegistryKey dimension); /** * Sends a packet via the wireless network. @@ -182,5 +184,5 @@ public interface NetworkAPI { * @param nbt the tag to load the packet from. * @return the loaded packet. */ - Packet newPacket(NBTTagCompound nbt); + Packet newPacket(CompoundNBT nbt); } \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/driver/DriverBlock.java b/src/main/java/li/cil/oc/api/driver/DriverBlock.java index 9dd7891c2c..69fd372c06 100644 --- a/src/main/java/li/cil/oc/api/driver/DriverBlock.java +++ b/src/main/java/li/cil/oc/api/driver/DriverBlock.java @@ -2,7 +2,7 @@ import li.cil.oc.api.network.ManagedEnvironment; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.world.World; /** @@ -44,7 +44,7 @@ public interface DriverBlock { * @param side the side of the block to check. * @return true if the block is supported; false otherwise. */ - boolean worksWith(World world, BlockPos pos, EnumFacing side); + boolean worksWith(World world, BlockPos pos, Direction side); /** * Create a new managed environment interfacing the specified block. @@ -67,5 +67,5 @@ public interface DriverBlock { * @param side the side of the block to check. * @return the environment for the block at that location. */ - ManagedEnvironment createEnvironment(World world, BlockPos pos, EnumFacing side); + ManagedEnvironment createEnvironment(World world, BlockPos pos, Direction side); } \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/driver/DriverItem.java b/src/main/java/li/cil/oc/api/driver/DriverItem.java index 965d658182..98b42d2823 100644 --- a/src/main/java/li/cil/oc/api/driver/DriverItem.java +++ b/src/main/java/li/cil/oc/api/driver/DriverItem.java @@ -2,7 +2,7 @@ import li.cil.oc.api.network.ManagedEnvironment; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; /** * Interface for item component drivers. @@ -110,5 +110,5 @@ public interface DriverItem { * @return the tag to use for saving and loading, or null to use * the default tag oc:data. */ - NBTTagCompound dataTag(ItemStack stack); + CompoundNBT dataTag(ItemStack stack); } \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/driver/InventoryProvider.java b/src/main/java/li/cil/oc/api/driver/InventoryProvider.java index 4308b454a0..e231318a2d 100644 --- a/src/main/java/li/cil/oc/api/driver/InventoryProvider.java +++ b/src/main/java/li/cil/oc/api/driver/InventoryProvider.java @@ -1,6 +1,6 @@ package li.cil.oc.api.driver; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; @@ -13,7 +13,7 @@ * the inventory controller upgrade, for example. *

* Implementations returned by {@link #getInventory} should save changes - * back to the item stack when {@link IInventory#markDirty()} is called. + * back to the item stack when {@link IInventory#setChanged()} is called. * Return null if the specified stack is not supported. */ public interface InventoryProvider { @@ -24,7 +24,7 @@ public interface InventoryProvider { * @param player the player holding the item, may be null. * @return true if the stack is supported, false otherwise. */ - boolean worksWith(ItemStack stack, EntityPlayer player); + boolean worksWith(ItemStack stack, PlayerEntity player); /** * Get an inventory implementation that allows interfacing with the @@ -38,5 +38,5 @@ public interface InventoryProvider { * @param player the player holding the item, may be null. * @return the inventory representing the contents, or null. */ - IInventory getInventory(ItemStack stack, EntityPlayer player); + IInventory getInventory(ItemStack stack, PlayerEntity player); } diff --git a/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java b/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java index 838f5785ab..25cdfb9e5e 100644 --- a/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java +++ b/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java @@ -17,7 +17,7 @@ * suppress inventory functionality if your TileEntity implements IInventory. *

* To do so, implement this interface in the environment that you - * return from your driver's {@link DriverBlock#createEnvironment(net.minecraft.world.World, BlockPos, net.minecraft.util.EnumFacing)} + * return from your driver's {@link DriverBlock#createEnvironment(net.minecraft.world.World, BlockPos, net.minecraft.util.Direction)} * method, and provide the names of the allowed methods from {@link #whitelistedMethods()}. *

* Important: if multiple drivers apply to a single block that each diff --git a/src/main/java/li/cil/oc/api/driver/NamedBlock.java b/src/main/java/li/cil/oc/api/driver/NamedBlock.java index 91796fd1c2..4a869bd10f 100644 --- a/src/main/java/li/cil/oc/api/driver/NamedBlock.java +++ b/src/main/java/li/cil/oc/api/driver/NamedBlock.java @@ -9,7 +9,7 @@ *

* This was previously to be implemented on the driver itself, but that has been * deprecated. Implement it in the environment returned from the block driver's - * {@link DriverBlock#createEnvironment(net.minecraft.world.World, BlockPos, net.minecraft.util.EnumFacing)} + * {@link DriverBlock#createEnvironment(net.minecraft.world.World, BlockPos, net.minecraft.util.Direction)} * method instead. */ public interface NamedBlock { diff --git a/src/main/java/li/cil/oc/api/driver/item/UpgradeRenderer.java b/src/main/java/li/cil/oc/api/driver/item/UpgradeRenderer.java index 87bc9f1ad0..5edf64b84b 100644 --- a/src/main/java/li/cil/oc/api/driver/item/UpgradeRenderer.java +++ b/src/main/java/li/cil/oc/api/driver/item/UpgradeRenderer.java @@ -1,10 +1,12 @@ package li.cil.oc.api.driver.item; +import com.mojang.blaze3d.matrix.MatrixStack; import li.cil.oc.api.event.RobotRenderEvent; import li.cil.oc.api.internal.Robot; +import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import java.util.Set; @@ -72,7 +74,7 @@ public interface UpgradeRenderer { * @param robot the robot the upgrade is rendered on. * @param pt partial tick time, e.g. for animations. */ - void render(ItemStack stack, RobotRenderEvent.MountPoint mountPoint, Robot robot, float pt); + void render(MatrixStack matrix, IRenderTypeBuffer buffer, ItemStack stack, RobotRenderEvent.MountPoint mountPoint, Robot robot, float pt); /** * Mount point names for {@link #computePreferredMountPoint}. diff --git a/src/main/java/li/cil/oc/api/driver/item/package-info.java b/src/main/java/li/cil/oc/api/driver/item/package-info.java index 61ba9e400f..ecb06d065a 100644 --- a/src/main/java/li/cil/oc/api/driver/item/package-info.java +++ b/src/main/java/li/cil/oc/api/driver/item/package-info.java @@ -4,10 +4,6 @@ * These interfaces allow specializing item drivers to provide static data, * that is without creating an actual environment. */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|driver|item", - apiVersion = API.VERSION) package li.cil.oc.api.driver.item; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/driver/package-info.java b/src/main/java/li/cil/oc/api/driver/package-info.java index 76cca59f09..1e8d4c5d80 100644 --- a/src/main/java/li/cil/oc/api/driver/package-info.java +++ b/src/main/java/li/cil/oc/api/driver/package-info.java @@ -4,10 +4,6 @@ * Drivers are used to add items and third party blocks to the internal network, * which is mostly used to make components wrapping them available to computers. */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|driver", - apiVersion = API.VERSION) package li.cil.oc.api.driver; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/event/FileSystemAccessEvent.java b/src/main/java/li/cil/oc/api/event/FileSystemAccessEvent.java index 4a649f7ea2..3e2f9bfb93 100644 --- a/src/main/java/li/cil/oc/api/event/FileSystemAccessEvent.java +++ b/src/main/java/li/cil/oc/api/event/FileSystemAccessEvent.java @@ -1,11 +1,11 @@ package li.cil.oc.api.event; import li.cil.oc.api.network.Node; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; -import net.minecraftforge.fml.common.eventhandler.Cancelable; -import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.eventbus.api.Cancelable; +import net.minecraftforge.eventbus.api.Event; /** * Events for handling file system access and representing it on the client. @@ -33,7 +33,7 @@ public class FileSystemAccessEvent extends Event { protected TileEntity tileEntity; - protected NBTTagCompound data; + protected CompoundNBT data; /** * Constructor for tile entity hosted file systems. @@ -42,12 +42,12 @@ public class FileSystemAccessEvent extends Event { * @param tileEntity the tile entity hosting the file system. * @param data the additional data. */ - protected FileSystemAccessEvent(String sound, TileEntity tileEntity, NBTTagCompound data) { + protected FileSystemAccessEvent(String sound, TileEntity tileEntity, CompoundNBT data) { this.sound = sound; - this.world = tileEntity.getWorld(); - this.x = tileEntity.getPos().getX() + 0.5; - this.y = tileEntity.getPos().getY() + 0.5; - this.z = tileEntity.getPos().getZ() + 0.5; + this.world = tileEntity.getLevel(); + this.x = tileEntity.getBlockPos().getX() + 0.5; + this.y = tileEntity.getBlockPos().getY() + 0.5; + this.z = tileEntity.getBlockPos().getZ() + 0.5; this.tileEntity = tileEntity; this.data = data; } @@ -62,7 +62,7 @@ protected FileSystemAccessEvent(String sound, TileEntity tileEntity, NBTTagCompo * @param z the z coordinate of the file system's container. * @param data the additional data. */ - protected FileSystemAccessEvent(String sound, World world, double x, double y, double z, NBTTagCompound data) { + protected FileSystemAccessEvent(String sound, World world, double x, double y, double z, CompoundNBT data) { this.sound = sound; this.world = world; this.x = x; @@ -113,7 +113,7 @@ public double getZ() { * Important: this can be null, which is usually the * case when the container is an entity or item. */ - public TileEntity getTileEntity() { + public TileEntity getBlockEntity() { return tileEntity; } @@ -121,7 +121,7 @@ public TileEntity getTileEntity() { * Addition custom data, this is used to transmit the number of the server * in a server rack the file system lives in, for example. */ - public NBTTagCompound getData() { + public CompoundNBT getData() { return data; } @@ -129,12 +129,12 @@ public static final class Server extends FileSystemAccessEvent { private Node node; public Server(String sound, TileEntity tileEntity, Node node) { - super(sound, tileEntity, new NBTTagCompound()); + super(sound, tileEntity, new CompoundNBT()); this.node = node; } public Server(String sound, World world, double x, double y, double z, Node node) { - super(sound, world, x, y, z, new NBTTagCompound()); + super(sound, world, x, y, z, new CompoundNBT()); this.node = node; } @@ -154,7 +154,7 @@ public static final class Client extends FileSystemAccessEvent { * @param tileEntity the tile entity hosting the file system. * @param data the additional data. */ - public Client(String sound, TileEntity tileEntity, NBTTagCompound data) { + public Client(String sound, TileEntity tileEntity, CompoundNBT data) { super(sound, tileEntity, data); } @@ -168,7 +168,7 @@ public Client(String sound, TileEntity tileEntity, NBTTagCompound data) { * @param z the z coordinate of the file system's container. * @param data the additional data. */ - public Client(String sound, World world, double x, double y, double z, NBTTagCompound data) { + public Client(String sound, World world, double x, double y, double z, CompoundNBT data) { super(sound, world, x, y, z, data); } } diff --git a/src/main/java/li/cil/oc/api/event/GeolyzerEvent.java b/src/main/java/li/cil/oc/api/event/GeolyzerEvent.java index 1dc5865567..62437d6dc1 100644 --- a/src/main/java/li/cil/oc/api/event/GeolyzerEvent.java +++ b/src/main/java/li/cil/oc/api/event/GeolyzerEvent.java @@ -2,8 +2,8 @@ import li.cil.oc.api.network.EnvironmentHost; import net.minecraft.util.math.BlockPos; -import net.minecraftforge.fml.common.eventhandler.Cancelable; -import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.eventbus.api.Cancelable; +import net.minecraftforge.eventbus.api.Event; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/li/cil/oc/api/event/NetworkActivityEvent.java b/src/main/java/li/cil/oc/api/event/NetworkActivityEvent.java index 918f31fe6d..2e2ae9f762 100644 --- a/src/main/java/li/cil/oc/api/event/NetworkActivityEvent.java +++ b/src/main/java/li/cil/oc/api/event/NetworkActivityEvent.java @@ -1,10 +1,10 @@ package li.cil.oc.api.event; import li.cil.oc.api.network.Node; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; -import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.eventbus.api.Event; /** * Events for handling network activity and representing it on the client. @@ -29,7 +29,7 @@ public class NetworkActivityEvent extends Event { protected TileEntity tileEntity; - protected NBTTagCompound data; + protected CompoundNBT data; /** * Constructor for tile entity hosted network cards. @@ -37,11 +37,11 @@ public class NetworkActivityEvent extends Event { * @param tileEntity the tile entity hosting the network card. * @param data the additional data. */ - protected NetworkActivityEvent(TileEntity tileEntity, NBTTagCompound data) { - this.world = tileEntity.getWorld(); - this.x = tileEntity.getPos().getX() + 0.5; - this.y = tileEntity.getPos().getY() + 0.5; - this.z = tileEntity.getPos().getZ() + 0.5; + protected NetworkActivityEvent(TileEntity tileEntity, CompoundNBT data) { + this.world = tileEntity.getLevel(); + this.x = tileEntity.getBlockPos().getX() + 0.5; + this.y = tileEntity.getBlockPos().getY() + 0.5; + this.z = tileEntity.getBlockPos().getZ() + 0.5; this.tileEntity = tileEntity; this.data = data; } @@ -55,7 +55,7 @@ protected NetworkActivityEvent(TileEntity tileEntity, NBTTagCompound data) { * @param z the z coordinate of the network card's container. * @param data the additional data. */ - protected NetworkActivityEvent(World world, double x, double y, double z, NBTTagCompound data) { + protected NetworkActivityEvent(World world, double x, double y, double z, CompoundNBT data) { this.world = world; this.x = x; this.y = y; @@ -98,7 +98,7 @@ public double getZ() { * Important: this can be null, which is usually the * case when the container is an entity or item. */ - public TileEntity getTileEntity() { + public TileEntity getBlockEntity() { return tileEntity; } @@ -106,7 +106,7 @@ public TileEntity getTileEntity() { * Addition custom data, this is used to transmit the number of the server * in a server rack the network card lives in, for example. */ - public NBTTagCompound getData() { + public CompoundNBT getData() { return data; } @@ -114,12 +114,12 @@ public static final class Server extends NetworkActivityEvent { private Node node; public Server(TileEntity tileEntity, Node node) { - super(tileEntity, new NBTTagCompound()); + super(tileEntity, new CompoundNBT()); this.node = node; } public Server(World world, double x, double y, double z, Node node) { - super(world, x, y, z, new NBTTagCompound()); + super(world, x, y, z, new CompoundNBT()); this.node = node; } @@ -138,7 +138,7 @@ public static final class Client extends NetworkActivityEvent { * @param tileEntity the tile entity hosting the network card. * @param data the additional data. */ - public Client(TileEntity tileEntity, NBTTagCompound data) { + public Client(TileEntity tileEntity, CompoundNBT data) { super(tileEntity, data); } @@ -151,7 +151,7 @@ public Client(TileEntity tileEntity, NBTTagCompound data) { * @param z the z coordinate of the network card's container. * @param data the additional data. */ - public Client(World world, double x, double y, double z, NBTTagCompound data) { + public Client(World world, double x, double y, double z, CompoundNBT data) { super(world, x, y, z, data); } } diff --git a/src/main/java/li/cil/oc/api/event/RackMountableRenderEvent.java b/src/main/java/li/cil/oc/api/event/RackMountableRenderEvent.java index fc77c14fc1..4f689859c9 100644 --- a/src/main/java/li/cil/oc/api/event/RackMountableRenderEvent.java +++ b/src/main/java/li/cil/oc/api/event/RackMountableRenderEvent.java @@ -1,19 +1,16 @@ package li.cil.oc.api.event; +import com.mojang.blaze3d.matrix.MatrixStack; import li.cil.oc.api.component.RackMountable; import li.cil.oc.api.internal.Rack; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumFacing; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.eventhandler.Cancelable; -import net.minecraftforge.fml.common.eventhandler.Event; -import org.lwjgl.opengl.GL11; +import net.minecraftforge.eventbus.api.Cancelable; +import net.minecraftforge.eventbus.api.Event; /** * Fired to allow rendering a custom overlay for {@link li.cil.oc.api.component.RackMountable}s. @@ -39,9 +36,9 @@ public abstract class RackMountableRenderEvent extends Event { * * @see RackMountable#getData() */ - public final NBTTagCompound data; + public final CompoundNBT data; - public RackMountableRenderEvent(Rack rack, int mountable, NBTTagCompound data) { + public RackMountableRenderEvent(Rack rack, int mountable, CompoundNBT data) { this.rack = rack; this.mountable = mountable; this.data = data; @@ -62,14 +59,14 @@ public static class Block extends RackMountableRenderEvent { /** * The front-facing side, i.e. where the mountable is visible on the rack. */ - public final EnumFacing side; + public final Direction side; /** * Texture to use for the front of the mountable. */ private TextureAtlasSprite frontTextureOverride; - public Block(final Rack rack, final int mountable, final NBTTagCompound data, final EnumFacing side) { + public Block(final Rack rack, final int mountable, final CompoundNBT data, final Direction side) { super(rack, mountable, data); this.side = side; } @@ -94,7 +91,7 @@ public void setFrontTextureOverride(final TextureAtlasSprite texture) { /** * Fired when the dynamic rack model is rendered. *

- * Code here runs inside a TileEntitySpecialRenderer, so go nuts. This is + * Code here runs inside a TileEntityRenderer, so go nuts. This is * primarily meant to allow rendering custom overlays, such as LEDs. The GL state * will have been adjusted such that rendering a one by one quad starting at the * origin will fill the full front face of the rack (i.e. rotation and translation @@ -108,75 +105,35 @@ public void setFrontTextureOverride(final TextureAtlasSprite texture) { */ public static class TileEntity extends RackMountableRenderEvent { /** - * The vertical low and high texture coordinates for the mountable's slot. - *

- * This is purely for convenience; they're computed as (2/16)+i*(3/16). + * The transformation used by the rendering engine. */ - public final float v0, v1; - - public TileEntity(final Rack rack, final int mountable, final NBTTagCompound data, final float v0, final float v1) { - super(rack, mountable, data); - this.v0 = v0; - this.v1 = v1; - } + public final MatrixStack stack; /** - * Utility method for rendering a texture as the front-side overlay. - * - * @param texture the texture to use to render the overlay. + * An accessor to the renderer's buffer context. */ - public void renderOverlay(final ResourceLocation texture) { - renderOverlay(texture, 0, 1); - } + public final IRenderTypeBuffer typeBuffer; /** - * Utility method for rendering a texture as the front-side overlay - * over a specified horizontal area. - * - * @param texture the texture to use to render the overlay. - * @param u0 the lower end of the vertical area to render at. - * @param u1 the upper end of the vertical area to render at. + * Packed block light and overlay texture coordinates. */ - public void renderOverlay(final ResourceLocation texture, final float u0, final float u1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(texture); - final Tessellator t = Tessellator.getInstance(); - final BufferBuilder r = t.getBuffer(); - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - r.pos(u0, v1, 0).tex(u0, v1).endVertex(); - r.pos(u1, v1, 0).tex(u1, v1).endVertex(); - r.pos(u1, v0, 0).tex(u1, v0).endVertex(); - r.pos(u0, v0, 0).tex(u0, v0).endVertex(); - t.draw(); - } + public final int light, overlay; /** - * Utility method for rendering an atlas texture as the front-side overlay. - * - * @param texture the atlas texture to use to render the overlay. + * The vertical low and high texture coordinates for the mountable's slot. + *

+ * This is purely for convenience; they're computed as (2/16)+i*(3/16). */ - public void renderOverlayFromAtlas(final ResourceLocation texture) { - renderOverlayFromAtlas(texture, 0, 1); - } + public final float v0, v1; - /** - * Utility method for rendering an atlas texture as the front-side overlay - * over a specified horizontal area. - * - * @param texture the atlas texture to use to render the overlay. - * @param u0 the lower end of the vertical area to render at. - * @param u1 the upper end of the vertical area to render at. - */ - public void renderOverlayFromAtlas(final ResourceLocation texture, final float u0, final float u1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - final TextureAtlasSprite icon = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(texture.toString()); - final Tessellator t = Tessellator.getInstance(); - final BufferBuilder r = t.getBuffer(); - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - r.pos(u0, v1, 0).tex(icon.getInterpolatedU(u0 * 16), icon.getInterpolatedV(v1 * 16)).endVertex(); - r.pos(u1, v1, 0).tex(icon.getInterpolatedU(u1 * 16), icon.getInterpolatedV(v1 * 16)).endVertex(); - r.pos(u1, v0, 0).tex(icon.getInterpolatedU(u1 * 16), icon.getInterpolatedV(v0 * 16)).endVertex(); - r.pos(u0, v0, 0).tex(icon.getInterpolatedU(u0 * 16), icon.getInterpolatedV(v0 * 16)).endVertex(); - t.draw(); + public TileEntity(final Rack rack, final int mountable, final CompoundNBT data, final MatrixStack stack, final IRenderTypeBuffer typeBuffer, final int light, final int overlay, final float v0, final float v1) { + super(rack, mountable, data); + this.stack = stack; + this.typeBuffer = typeBuffer; + this.light = light; + this.overlay = overlay; + this.v0 = v0; + this.v1 = v1; } } } diff --git a/src/main/java/li/cil/oc/api/event/RobotAnalyzeEvent.java b/src/main/java/li/cil/oc/api/event/RobotAnalyzeEvent.java index b1497ab402..49309e9ded 100644 --- a/src/main/java/li/cil/oc/api/event/RobotAnalyzeEvent.java +++ b/src/main/java/li/cil/oc/api/event/RobotAnalyzeEvent.java @@ -1,7 +1,7 @@ package li.cil.oc.api.event; import li.cil.oc.api.internal.Agent; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; /** * Fired when an analyzer is used on a robot. @@ -12,9 +12,9 @@ public class RobotAnalyzeEvent extends RobotEvent { /** * The player that used the analyzer. */ - public final EntityPlayer player; + public final PlayerEntity player; - public RobotAnalyzeEvent(Agent agent, EntityPlayer player) { + public RobotAnalyzeEvent(Agent agent, PlayerEntity player) { super(agent); this.player = player; } diff --git a/src/main/java/li/cil/oc/api/event/RobotAttackEntityEvent.java b/src/main/java/li/cil/oc/api/event/RobotAttackEntityEvent.java index 55a7501888..a2ecac8141 100644 --- a/src/main/java/li/cil/oc/api/event/RobotAttackEntityEvent.java +++ b/src/main/java/li/cil/oc/api/event/RobotAttackEntityEvent.java @@ -2,7 +2,7 @@ import li.cil.oc.api.internal.Agent; import net.minecraft.entity.Entity; -import net.minecraftforge.fml.common.eventhandler.Cancelable; +import net.minecraftforge.eventbus.api.Cancelable; public class RobotAttackEntityEvent extends RobotEvent { /** diff --git a/src/main/java/li/cil/oc/api/event/RobotBreakBlockEvent.java b/src/main/java/li/cil/oc/api/event/RobotBreakBlockEvent.java index 5e11343aa5..2281d7d899 100644 --- a/src/main/java/li/cil/oc/api/event/RobotBreakBlockEvent.java +++ b/src/main/java/li/cil/oc/api/event/RobotBreakBlockEvent.java @@ -3,7 +3,7 @@ import li.cil.oc.api.internal.Agent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.eventhandler.Cancelable; +import net.minecraftforge.eventbus.api.Cancelable; public abstract class RobotBreakBlockEvent extends RobotEvent { protected RobotBreakBlockEvent(Agent agent) { diff --git a/src/main/java/li/cil/oc/api/event/RobotEvent.java b/src/main/java/li/cil/oc/api/event/RobotEvent.java index a8672a04b5..0fb168ac28 100644 --- a/src/main/java/li/cil/oc/api/event/RobotEvent.java +++ b/src/main/java/li/cil/oc/api/event/RobotEvent.java @@ -1,7 +1,7 @@ package li.cil.oc.api.event; import li.cil.oc.api.internal.Agent; -import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.eventbus.api.Event; /** * Base class for events generated by robots. diff --git a/src/main/java/li/cil/oc/api/event/RobotMoveEvent.java b/src/main/java/li/cil/oc/api/event/RobotMoveEvent.java index d1c8f7096c..d721e0e264 100644 --- a/src/main/java/li/cil/oc/api/event/RobotMoveEvent.java +++ b/src/main/java/li/cil/oc/api/event/RobotMoveEvent.java @@ -1,16 +1,16 @@ package li.cil.oc.api.event; import li.cil.oc.api.internal.Agent; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.fml.common.eventhandler.Cancelable; +import net.minecraft.util.Direction; +import net.minecraftforge.eventbus.api.Cancelable; public abstract class RobotMoveEvent extends RobotEvent { /** * The direction in which the robot will be moving. */ - public final EnumFacing direction; + public final Direction direction; - protected RobotMoveEvent(Agent agent, EnumFacing direction) { + protected RobotMoveEvent(Agent agent, Direction direction) { super(agent); this.direction = direction; } @@ -22,7 +22,7 @@ protected RobotMoveEvent(Agent agent, EnumFacing direction) { */ @Cancelable public static class Pre extends RobotMoveEvent { - public Pre(Agent agent, EnumFacing direction) { + public Pre(Agent agent, Direction direction) { super(agent, direction); } } @@ -31,7 +31,7 @@ public Pre(Agent agent, EnumFacing direction) { * Fired after a robot moved. */ public static class Post extends RobotMoveEvent { - public Post(Agent agent, EnumFacing direction) { + public Post(Agent agent, Direction direction) { super(agent, direction); } } diff --git a/src/main/java/li/cil/oc/api/event/RobotPlaceBlockEvent.java b/src/main/java/li/cil/oc/api/event/RobotPlaceBlockEvent.java index 36cb5e60f7..07df5919fd 100644 --- a/src/main/java/li/cil/oc/api/event/RobotPlaceBlockEvent.java +++ b/src/main/java/li/cil/oc/api/event/RobotPlaceBlockEvent.java @@ -4,7 +4,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.eventhandler.Cancelable; +import net.minecraftforge.eventbus.api.Cancelable; public abstract class RobotPlaceBlockEvent extends RobotEvent { /** diff --git a/src/main/java/li/cil/oc/api/event/RobotRenderEvent.java b/src/main/java/li/cil/oc/api/event/RobotRenderEvent.java index 4b20d0364b..9aeef42801 100644 --- a/src/main/java/li/cil/oc/api/event/RobotRenderEvent.java +++ b/src/main/java/li/cil/oc/api/event/RobotRenderEvent.java @@ -4,9 +4,10 @@ import li.cil.oc.api.internal.Agent; import li.cil.oc.api.internal.Robot; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.eventhandler.Cancelable; -import org.lwjgl.util.vector.Vector3f; -import org.lwjgl.util.vector.Vector4f; +import net.minecraftforge.eventbus.api.Cancelable; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.vector.Vector3f; +import net.minecraft.util.math.vector.Vector4f; import java.util.Set; @@ -34,9 +35,59 @@ public class RobotRenderEvent extends RobotEvent { */ public final MountPoint[] mountPoints; + /** + * Overrides the color of the robot chassis' light. Only used if greater + * or equal to zero. Consists of 8 bits per channel: red, green and blue. + * The color override does NOT apply to this color. + */ + public int lightColor; + + private float mulR, mulG, mulB; + public RobotRenderEvent(Agent agent, MountPoint[] mountPoints) { super(agent); this.mountPoints = mountPoints; + lightColor = -1; + mulR = mulG = mulB = 1.0f; + } + + /** + * Convenience method for setting {@link #lightColor}. Will clamp values + * to between 0 and 1 and pack them into an RGB integer. + */ + public void setLightColor(float r, float g, float b) { + int ir = MathHelper.floor(0.5f + 255 * MathHelper.clamp(r, 0.0f, 1.0f)); + int ig = MathHelper.floor(0.5f + 255 * MathHelper.clamp(g, 0.0f, 1.0f)); + int ib = MathHelper.floor(0.5f + 255 * MathHelper.clamp(b, 0.0f, 1.0f)); + lightColor = (ir << 16) | (ig << 8) | ib; + } + + /** + * Multiplies the color or the robot chassis by a certain value. Each + * color component is clamped to between 0 and 1. This multiplier is + * cumulative, meaning if it is update too many times the robot will + * end up black (multiplier zero). This does not affect the light in + * the middle of the robot, nor does it affect upgrades. + *

+ * Use {@link #getColorMultiplier()} to obtain the pure multiplier or + * {@link #getColorMultiplier(float, float, float)} if you need to mix + * your own color into it. + */ + public void multiplyColors(float r, float g, float b) { + mulR *= MathHelper.clamp(r, 0.0f, 1.0f); + mulG *= MathHelper.clamp(g, 0.0f, 1.0f); + mulB *= MathHelper.clamp(b, 0.0f, 1.0f); + } + + public int getColorMultiplier() { + return getColorValue(1.0f, 1.0f, 1.0f); + } + + public int getColorValue(float rm, float gm, float bm) { + int r = MathHelper.floor(0.5f + 255 * MathHelper.clamp(rm * mulR, 0.0f, 1.0f)); + int g = MathHelper.floor(0.5f + 255 * MathHelper.clamp(gm * mulG, 0.0f, 1.0f)); + int b = MathHelper.floor(0.5f + 255 * MathHelper.clamp(bm * mulB, 0.0f, 1.0f)); + return (r << 16) | (g << 8) | b; } /** diff --git a/src/main/java/li/cil/oc/api/event/SignChangeEvent.java b/src/main/java/li/cil/oc/api/event/SignChangeEvent.java index 64321c25f1..88a09b002f 100644 --- a/src/main/java/li/cil/oc/api/event/SignChangeEvent.java +++ b/src/main/java/li/cil/oc/api/event/SignChangeEvent.java @@ -1,30 +1,30 @@ package li.cil.oc.api.event; -import net.minecraft.tileentity.TileEntitySign; -import net.minecraftforge.fml.common.eventhandler.Cancelable; -import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraft.tileentity.SignTileEntity; +import net.minecraftforge.eventbus.api.Cancelable; +import net.minecraftforge.eventbus.api.Event; /** * A bit more specific sign change event that holds information about new text of the sign. Used in the sign upgrade. */ public abstract class SignChangeEvent extends Event { - public final TileEntitySign sign; + public final SignTileEntity sign; public final String[] lines; - private SignChangeEvent(TileEntitySign sign, String[] lines) { + private SignChangeEvent(SignTileEntity sign, String[] lines) { this.sign = sign; this.lines = lines; } @Cancelable public static class Pre extends SignChangeEvent { - public Pre(TileEntitySign sign, String[] lines) { + public Pre(SignTileEntity sign, String[] lines) { super(sign, lines); } } public static class Post extends SignChangeEvent { - public Post(TileEntitySign sign, String[] lines) { + public Post(SignTileEntity sign, String[] lines) { super(sign, lines); } } diff --git a/src/main/java/li/cil/oc/api/event/package-info.java b/src/main/java/li/cil/oc/api/event/package-info.java index 6173e66fad..f1758d349d 100644 --- a/src/main/java/li/cil/oc/api/event/package-info.java +++ b/src/main/java/li/cil/oc/api/event/package-info.java @@ -2,10 +2,6 @@ * Events dispatched by OpenComputers to allow other mods to hook into some * of its functionality. */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|event", - apiVersion = API.VERSION) package li.cil.oc.api.event; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/fs/package-info.java b/src/main/java/li/cil/oc/api/fs/package-info.java index 6c466110b1..46d9d5a620 100644 --- a/src/main/java/li/cil/oc/api/fs/package-info.java +++ b/src/main/java/li/cil/oc/api/fs/package-info.java @@ -13,10 +13,6 @@ * that can be added as component nodes to the network, so they can be used * from computers). */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|filesystem", - apiVersion = API.VERSION) package li.cil.oc.api.fs; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/internal/Agent.java b/src/main/java/li/cil/oc/api/internal/Agent.java index 6f78c196b6..53a71356f7 100644 --- a/src/main/java/li/cil/oc/api/internal/Agent.java +++ b/src/main/java/li/cil/oc/api/internal/Agent.java @@ -1,7 +1,7 @@ package li.cil.oc.api.internal; import li.cil.oc.api.machine.MachineHost; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.IInventory; import java.util.UUID; @@ -67,7 +67,7 @@ public interface Agent extends MachineHost, Rotatable { * * @return the fake player for the agent. */ - EntityPlayer player(); + PlayerEntity player(); /** * Get the name of this agent. diff --git a/src/main/java/li/cil/oc/api/internal/Drone.java b/src/main/java/li/cil/oc/api/internal/Drone.java index 45a9aba3d6..95fcfe7ffe 100644 --- a/src/main/java/li/cil/oc/api/internal/Drone.java +++ b/src/main/java/li/cil/oc/api/internal/Drone.java @@ -1,7 +1,7 @@ package li.cil.oc.api.internal; import li.cil.oc.api.network.EnvironmentHost; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.vector.Vector3d; /** * This interface is implemented as a marker by drones. @@ -20,7 +20,7 @@ public interface Drone extends Agent, EnvironmentHost, Rotatable, Tiered { /** * Get the current target coordinates of the drone. */ - Vec3d getTarget(); + Vector3d getTarget(); /** * Set the new target coordinates of the drone. @@ -29,7 +29,7 @@ public interface Drone extends Agent, EnvironmentHost, Rotatable, Tiered { * to avoid jitter on the client and floating point inaccuracies to * accumulate. */ - void setTarget(Vec3d value); + void setTarget(Vector3d value); /** * Get the drones velocity vector. @@ -38,5 +38,5 @@ public interface Drone extends Agent, EnvironmentHost, Rotatable, Tiered { * so you can cast this to {@link net.minecraft.entity.Entity} and use that * instead, if you'd like. */ - Vec3d getVelocity(); + Vector3d getVelocity(); } diff --git a/src/main/java/li/cil/oc/api/internal/Keyboard.java b/src/main/java/li/cil/oc/api/internal/Keyboard.java index 7fdbf325a7..9ac4c7b6ed 100644 --- a/src/main/java/li/cil/oc/api/internal/Keyboard.java +++ b/src/main/java/li/cil/oc/api/internal/Keyboard.java @@ -2,7 +2,7 @@ import li.cil.oc.api.Persistable; import li.cil.oc.api.network.Environment; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; /** * This interface is implemented by the keyboard component, to allow more @@ -42,6 +42,6 @@ interface UsabilityChecker { * @param player the player to check for. * @return whether the keyboard is usable by the player. */ - boolean isUsableByPlayer(Keyboard keyboard, EntityPlayer player); + boolean isUsableByPlayer(Keyboard keyboard, PlayerEntity player); } } diff --git a/src/main/java/li/cil/oc/api/internal/Rack.java b/src/main/java/li/cil/oc/api/internal/Rack.java index 46aa88d3bc..9a11421a1b 100644 --- a/src/main/java/li/cil/oc/api/internal/Rack.java +++ b/src/main/java/li/cil/oc/api/internal/Rack.java @@ -4,7 +4,7 @@ import li.cil.oc.api.network.EnvironmentHost; import li.cil.oc.api.network.SidedEnvironment; import net.minecraft.inventory.IInventory; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; /** * This interface is implemented by the rack tile entity. @@ -48,7 +48,7 @@ public interface Rack extends SidedEnvironment, EnvironmentHost, Rotatable, IInv * @param slot the slot of the mountable to get the data for. * @return the data of the mountable in that slot, or null. */ - NBTTagCompound getMountableData(int slot); + CompoundNBT getMountableData(int slot); /** * Mark the mountable in the specified slot as changed. diff --git a/src/main/java/li/cil/oc/api/internal/Robot.java b/src/main/java/li/cil/oc/api/internal/Robot.java index ca5efa25fa..a94387a37c 100644 --- a/src/main/java/li/cil/oc/api/internal/Robot.java +++ b/src/main/java/li/cil/oc/api/internal/Robot.java @@ -3,8 +3,8 @@ import li.cil.oc.api.network.EnvironmentHost; import li.cil.oc.api.network.Environment; import net.minecraft.inventory.ISidedInventory; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; /** * This interface allows interaction with robots. @@ -74,7 +74,7 @@ public interface Robot extends Agent, Environment, EnvironmentHost, Tiered, ISid * to know whether to resume animations or not, based on whether the robot * is currently powered on or not. */ - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) boolean shouldAnimate(); } diff --git a/src/main/java/li/cil/oc/api/internal/Rotatable.java b/src/main/java/li/cil/oc/api/internal/Rotatable.java index 2695770f15..af1d6ffedc 100644 --- a/src/main/java/li/cil/oc/api/internal/Rotatable.java +++ b/src/main/java/li/cil/oc/api/internal/Rotatable.java @@ -1,7 +1,7 @@ package li.cil.oc.api.internal; import li.cil.oc.api.driver.DriverItem; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; /** * This interface is implemented by the computer case and robot tile entities @@ -32,7 +32,7 @@ public interface Rotatable { * * @return the current facing. */ - EnumFacing facing(); + Direction facing(); /** * Converts a facing relative to the block's local coordinate @@ -45,7 +45,7 @@ public interface Rotatable { * @param value the value to translate. * @return the translated orientation. */ - EnumFacing toGlobal(EnumFacing value); + Direction toGlobal(Direction value); /** * Converts a global orientation to a facing relative to the @@ -58,5 +58,5 @@ public interface Rotatable { * @param value the value to translate. * @return the translated orientation. */ - EnumFacing toLocal(EnumFacing value); + Direction toLocal(Direction value); } diff --git a/src/main/java/li/cil/oc/api/internal/Tablet.java b/src/main/java/li/cil/oc/api/internal/Tablet.java index e042685ac7..1b478170fb 100644 --- a/src/main/java/li/cil/oc/api/internal/Tablet.java +++ b/src/main/java/li/cil/oc/api/internal/Tablet.java @@ -2,7 +2,7 @@ import li.cil.oc.api.network.EnvironmentHost; import li.cil.oc.api.machine.MachineHost; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; /** * This interface is implemented as a marker by tablets. @@ -34,5 +34,5 @@ public interface Tablet extends EnvironmentHost, MachineHost, Rotatable { * * @return the player last holding the tablet. */ - EntityPlayer player(); + PlayerEntity player(); } diff --git a/src/main/java/li/cil/oc/api/internal/TextBuffer.java b/src/main/java/li/cil/oc/api/internal/TextBuffer.java index 2c7d3bcc15..76f13c9d4e 100644 --- a/src/main/java/li/cil/oc/api/internal/TextBuffer.java +++ b/src/main/java/li/cil/oc/api/internal/TextBuffer.java @@ -1,10 +1,11 @@ package li.cil.oc.api.internal; +import com.mojang.blaze3d.matrix.MatrixStack; import li.cil.oc.api.Persistable; import li.cil.oc.api.network.ManagedEnvironment; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; /** * This interface implements functionality for displaying and manipulating @@ -446,8 +447,8 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @return true if the displayed content changed since the last * call to this method. */ - @SideOnly(Side.CLIENT) - boolean renderText(); + @OnlyIn(Dist.CLIENT) + boolean renderText(MatrixStack stack); /** * The natural width of the rendered text. @@ -458,7 +459,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * * @return the total width of the rendered buffer, in pixels. */ - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) int renderWidth(); /** @@ -470,7 +471,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * * @return the total height of the rendered buffer, in pixels. */ - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) int renderHeight(); /** @@ -481,7 +482,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * * @param enabled whether the text buffer should be rendered. */ - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) void setRenderingEnabled(boolean enabled); /** @@ -489,7 +490,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * * @see #setRenderingEnabled(boolean) */ - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) boolean isRenderingEnabled(); // ----------------------------------------------------------------------- // @@ -505,7 +506,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @param code the key code of the pressed key. * @param player the player that pressed the key. Pass null on the client side. */ - void keyDown(char character, int code, EntityPlayer player); + void keyDown(char character, int code, PlayerEntity player); /** * Signals a key up event for the buffer. @@ -518,7 +519,20 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @param code the key code of the released key. * @param player the player that released the key. Pass null on the client side. */ - void keyUp(char character, int code, EntityPlayer player); + void keyUp(char character, int code, PlayerEntity player); + + /** + * Signals a code-point (text) event for the buffer. + *

+ * On the client side this causes a packet to be sent to the server. On the + * server side this will trigger a message that will be picked up by + * keyboards, which will then cause a signal in attached machines. + * + * @param character the character of the released key. + * @param codePoint the code point being typed. + * @param player the player that typed the code point. Pass null on the client side. + */ + void textInput(int codePoint, PlayerEntity player); /** * Signals a clipboard paste event for the buffer. @@ -530,7 +544,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @param value the text that was pasted. * @param player the player that pasted the text. Pass null on the client side. */ - void clipboard(String value, EntityPlayer player); + void clipboard(String value, PlayerEntity player); /** * Signals a mouse button down event for the buffer. @@ -543,7 +557,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @param button the button of the mouse that was pressed. * @param player the player that pressed the mouse button. Pass null on the client side. */ - void mouseDown(double x, double y, int button, EntityPlayer player); + void mouseDown(double x, double y, int button, PlayerEntity player); /** * Signals a mouse drag event for the buffer. @@ -556,7 +570,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @param button the button of the mouse that is pressed. * @param player the player that moved the mouse. Pass null on the client side. */ - void mouseDrag(double x, double y, int button, EntityPlayer player); + void mouseDrag(double x, double y, int button, PlayerEntity player); /** * Signals a mouse button release event for the buffer. @@ -569,7 +583,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @param button the button of the mouse that was released. * @param player the player that released the mouse button. Pass null on the client side. */ - void mouseUp(double x, double y, int button, EntityPlayer player); + void mouseUp(double x, double y, int button, PlayerEntity player); /** * Signals a mouse wheel scroll event for the buffer. @@ -582,7 +596,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { * @param delta indicates the direction of the mouse scroll. * @param player the player that scrolled the mouse wheel. Pass null on the client side. */ - void mouseScroll(double x, double y, int delta, EntityPlayer player); + void mouseScroll(double x, double y, int delta, PlayerEntity player); // ----------------------------------------------------------------------- // diff --git a/src/main/java/li/cil/oc/api/internal/Wrench.java b/src/main/java/li/cil/oc/api/internal/Wrench.java index f1584824af..7609aa8e3e 100644 --- a/src/main/java/li/cil/oc/api/internal/Wrench.java +++ b/src/main/java/li/cil/oc/api/internal/Wrench.java @@ -1,6 +1,6 @@ package li.cil.oc.api.internal; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -25,5 +25,5 @@ public interface Wrench { * @param simulate whether to simulate the usage. * @return whether the wrench can be used on the block. */ - boolean useWrenchOnBlock(EntityPlayer player, World world, BlockPos pos, boolean simulate); + boolean useWrenchOnBlock(PlayerEntity player, World world, BlockPos pos, boolean simulate); } diff --git a/src/main/java/li/cil/oc/api/internal/package-info.java b/src/main/java/li/cil/oc/api/internal/package-info.java index 0cea951a40..f07112644f 100644 --- a/src/main/java/li/cil/oc/api/internal/package-info.java +++ b/src/main/java/li/cil/oc/api/internal/package-info.java @@ -13,10 +13,6 @@ * used inside the specified environment (where the environment class may * be assignable to one of the interfaces in this package). */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|internal", - apiVersion = API.VERSION) package li.cil.oc.api.internal; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/machine/Architecture.java b/src/main/java/li/cil/oc/api/machine/Architecture.java index 0bf190b44d..05d431da0c 100644 --- a/src/main/java/li/cil/oc/api/machine/Architecture.java +++ b/src/main/java/li/cil/oc/api/machine/Architecture.java @@ -1,7 +1,7 @@ package li.cil.oc.api.machine; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; import java.lang.annotation.*; @@ -134,13 +134,13 @@ public interface Architecture { /** * Restores the state of this architecture as previously saved in - * {@link #save(NBTTagCompound)}. The architecture should be in the same + * {@link #saveData(CompoundNBT)}. The architecture should be in the same * state it was when it was saved after this, so it can be resumed from * whatever state the owning machine was in when it was saved. * * @param nbt the tag compound to save to. */ - void load(NBTTagCompound nbt); + void loadData(CompoundNBT nbt); /** * Saves the architecture for later restoration, e.g. across games or chunk @@ -151,7 +151,7 @@ public interface Architecture { * * @param nbt the tag compound to save to. */ - void save(NBTTagCompound nbt); + void saveData(CompoundNBT nbt); /** * Architectures can be annotated with this to provide a nice display name. diff --git a/src/main/java/li/cil/oc/api/machine/Context.java b/src/main/java/li/cil/oc/api/machine/Context.java index b92aa75096..66dd616cb9 100644 --- a/src/main/java/li/cil/oc/api/machine/Context.java +++ b/src/main/java/li/cil/oc/api/machine/Context.java @@ -36,7 +36,7 @@ public interface Context { * Use this to check whether you should signal something to the computer, * for example. Note that for signals triggered via network messages there * is a computer.checked_signal message, that expects an - * EntityPlayer as the first argument and performs this check + * PlayerEntity as the first argument and performs this check * before pushing the signal. * * @param player the name of the player to check for. @@ -171,7 +171,7 @@ public interface Context { *

  • Strings.
  • *
  • Byte arrays (which appear as strings on the Lua side, e.g.).
  • *
  • Maps if and only if both keys and values are strings.
  • - *
  • NBTTagCompounds.
  • + *
  • CompoundNBTs.
  • * * If an unsupported type is specified the method will enqueue nothing * instead, resulting in a nil on the Lua side, e.g., and log a diff --git a/src/main/java/li/cil/oc/api/machine/package-info.java b/src/main/java/li/cil/oc/api/machine/package-info.java index 09b038befd..1f5c666e0f 100644 --- a/src/main/java/li/cil/oc/api/machine/package-info.java +++ b/src/main/java/li/cil/oc/api/machine/package-info.java @@ -16,10 +16,6 @@ * implemented, but merely to allow accessing some mod internals in a regulated * fashion, such as {@link li.cil.oc.api.internal.Robot}. */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|machine", - apiVersion = API.VERSION) package li.cil.oc.api.machine; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/manual/ImageRenderer.java b/src/main/java/li/cil/oc/api/manual/ImageRenderer.java index 2dcad21f77..0e1a445481 100644 --- a/src/main/java/li/cil/oc/api/manual/ImageRenderer.java +++ b/src/main/java/li/cil/oc/api/manual/ImageRenderer.java @@ -1,5 +1,7 @@ package li.cil.oc.api.manual; +import com.mojang.blaze3d.matrix.MatrixStack; + /** * This allows implementing custom image renderers. *

    @@ -15,7 +17,7 @@ public interface ImageRenderer { * The width of the area this renderer uses. *

    * This is used to offset the OpenGL state properly before calling - * {@link #render(int, int)}, to correctly align the image horizontally. + * {@link #render(MatrixStack, int, int)}, to correctly align the image horizontally. * * @return the width of the rendered image. */ @@ -25,7 +27,7 @@ public interface ImageRenderer { * The height of the area this renderer uses. *

    * This is used to offset the OpenGL state properly before calling - * {@link #render(int, int)}, as well as to know where to resume rendering + * {@link #render(MatrixStack, int, int)}, as well as to know where to resume rendering * other content below the image. * * @return the height of the rendered image. @@ -40,8 +42,9 @@ public interface ImageRenderer { * (getWidth,getHeight,*), i.e. translation and scaling are taken care * of for you. * + * @param stack the render transformation for this image * @param mouseX the X position of the mouse relative to the element. * @param mouseY the Y position of the mouse relative to the element. */ - void render(int mouseX, int mouseY); + void render(MatrixStack stack, int mouseX, int mouseY); } diff --git a/src/main/java/li/cil/oc/api/manual/PathProvider.java b/src/main/java/li/cil/oc/api/manual/PathProvider.java index 4f796f2b2f..dc9701d87e 100644 --- a/src/main/java/li/cil/oc/api/manual/PathProvider.java +++ b/src/main/java/li/cil/oc/api/manual/PathProvider.java @@ -16,7 +16,7 @@ *

    * Note that you can use the special variable %LANGUAGE% in your * paths, for language agnostic paths. These will be resolved to the currently - * set language, falling back to en_US, during actual content lookup. + * set language, falling back to en_us, during actual content lookup. */ public interface PathProvider { /** diff --git a/src/main/java/li/cil/oc/api/manual/TabIconRenderer.java b/src/main/java/li/cil/oc/api/manual/TabIconRenderer.java index ee7af3a746..d8e68167c9 100644 --- a/src/main/java/li/cil/oc/api/manual/TabIconRenderer.java +++ b/src/main/java/li/cil/oc/api/manual/TabIconRenderer.java @@ -1,7 +1,8 @@ package li.cil.oc.api.manual; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import com.mojang.blaze3d.matrix.MatrixStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; /** * Allows defining a renderer for a manual tab. @@ -21,6 +22,6 @@ public interface TabIconRenderer { * This should render something in a 16x16 area. The OpenGL state has been * adjusted so that drawing starts at (0,0,0), and should go to (16,16,0). */ - @SideOnly(Side.CLIENT) - void render(); + @OnlyIn(Dist.CLIENT) + void render(MatrixStack stack); } diff --git a/src/main/java/li/cil/oc/api/manual/package-info.java b/src/main/java/li/cil/oc/api/manual/package-info.java index eba0a4c2e9..cb61332b7c 100644 --- a/src/main/java/li/cil/oc/api/manual/package-info.java +++ b/src/main/java/li/cil/oc/api/manual/package-info.java @@ -5,10 +5,6 @@ * other mod that may choose to add its documentation to it, such as addon * mods. */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|manual", - apiVersion = API.VERSION) package li.cil.oc.api.manual; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/nanomachines/BehaviorProvider.java b/src/main/java/li/cil/oc/api/nanomachines/BehaviorProvider.java index 4e0ecf9525..69bbadc9ed 100644 --- a/src/main/java/li/cil/oc/api/nanomachines/BehaviorProvider.java +++ b/src/main/java/li/cil/oc/api/nanomachines/BehaviorProvider.java @@ -1,7 +1,7 @@ package li.cil.oc.api.nanomachines; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.CompoundNBT; /** * Implemented by providers for behaviors. @@ -26,12 +26,12 @@ public interface BehaviorProvider { * Note that this is only called on the server side when reconfiguring * nanomachines. If you have a behavior that actually acts client-only, * you still need to return it here, as it will be synchronized to the - * client using {@link #writeToNBT} and {@link #readFromNBT}. + * client using {@link #save} and {@link #load}. * * @param player the player the behaviors should be created for. * @return list of new behaviors, may be null. */ - Iterable createBehaviors(EntityPlayer player); + Iterable createBehaviors(PlayerEntity player); /** * Write a behavior to NBT. @@ -45,7 +45,7 @@ public interface BehaviorProvider { * @param behavior the behavior to serialize. * @return the serialized representation of the specified behavior. */ - NBTTagCompound writeToNBT(Behavior behavior); + CompoundNBT save(Behavior behavior); /** * Restore a behavior from NBT. @@ -62,5 +62,5 @@ public interface BehaviorProvider { * @param nbt the tag to restore the behavior from. * @return the restored behavior, or null if unhandled. */ - Behavior readFromNBT(EntityPlayer player, NBTTagCompound nbt); + Behavior load(PlayerEntity player, CompoundNBT nbt); } diff --git a/src/main/java/li/cil/oc/api/network/Analyzable.java b/src/main/java/li/cil/oc/api/network/Analyzable.java index 204d577209..3fab595c6a 100644 --- a/src/main/java/li/cil/oc/api/network/Analyzable.java +++ b/src/main/java/li/cil/oc/api/network/Analyzable.java @@ -1,7 +1,7 @@ package li.cil.oc.api.network; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EnumFacing; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Direction; /** * Allows defining a callback for when a block is right-clicked with an @@ -31,5 +31,5 @@ public interface Analyzable { * @return the nodes to display information for, usually an environment's * main node (i.e. this.node()). */ - Node[] onAnalyze(EntityPlayer player, EnumFacing side, float hitX, float hitY, float hitZ); + Node[] onAnalyze(PlayerEntity player, Direction side, float hitX, float hitY, float hitZ); } diff --git a/src/main/java/li/cil/oc/api/network/Environment.java b/src/main/java/li/cil/oc/api/network/Environment.java index 906543874d..b0b63eccd1 100644 --- a/src/main/java/li/cil/oc/api/network/Environment.java +++ b/src/main/java/li/cil/oc/api/network/Environment.java @@ -18,20 +18,20 @@ * When a tile entity implements this interface a good way of connecting and * disconnecting is the following pattern: *

    - *     void updateEntity() {
    - *         super.updateEntity()
    + *     void tick() {
    + *         super.tick()
      *         if (node != null && node.network == null) {
      *             api.Network.joinOrCreateNetwork(this);
      *         }
      *     }
      *
    - *     void onChunkUnload() {
    - *         super.onChunkUnload()
    + *     void onChunkUnloaded() {
    + *         super.onChunkUnloaded()
      *         if (node != null) node.remove()
      *     }
      *
    - *     void invalidate() {
    - *         super.invalidate()
    + *     void setRemoved() {
    + *         super.setRemoved()
      *         if (node != null) node.remove()
      *     }
      * 
    diff --git a/src/main/java/li/cil/oc/api/network/Network.java b/src/main/java/li/cil/oc/api/network/Network.java index e1d6fa8931..577eafe17e 100644 --- a/src/main/java/li/cil/oc/api/network/Network.java +++ b/src/main/java/li/cil/oc/api/network/Network.java @@ -75,8 +75,8 @@ public interface Network { * Removes a node from the network. *

    * This should be called by nodes when they are destroyed (e.g. in - * {@link net.minecraft.tileentity.TileEntity#invalidate()}) or unloaded - * (e.g. in {@link net.minecraft.tileentity.TileEntity#onChunkUnload()}). + * {@link net.minecraft.tileentity.TileEntity#setRemoved()}) or unloaded + * (e.g. in {@link net.minecraft.tileentity.TileEntity#onChunkUnloaded()}). * Removing the node can lead to one or more new networks if it was the a * bridge node, i.e. the only node connecting the resulting networks. * diff --git a/src/main/java/li/cil/oc/api/network/Packet.java b/src/main/java/li/cil/oc/api/network/Packet.java index 233e720187..572cf606e6 100644 --- a/src/main/java/li/cil/oc/api/network/Packet.java +++ b/src/main/java/li/cil/oc/api/network/Packet.java @@ -1,6 +1,6 @@ package li.cil.oc.api.network; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; /** * These packets represent messages sent using a network card or wireless @@ -65,5 +65,5 @@ public interface Packet { * Restore a packet saved like this using the factory method in the * {@link li.cil.oc.api.Network} class. */ - void save(NBTTagCompound nbt); + void saveData(CompoundNBT nbt); } diff --git a/src/main/java/li/cil/oc/api/network/SidedComponent.java b/src/main/java/li/cil/oc/api/network/SidedComponent.java index bc5eea0dd0..06c1ed13af 100644 --- a/src/main/java/li/cil/oc/api/network/SidedComponent.java +++ b/src/main/java/li/cil/oc/api/network/SidedComponent.java @@ -1,6 +1,6 @@ package li.cil.oc.api.network; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; /** * This is an extended version of {@link li.cil.oc.api.network.SimpleComponent} @@ -22,5 +22,5 @@ public interface SidedComponent { * @param side the side to check for. * @return whether the component may be connected to from the specified side. */ - boolean canConnectNode(EnumFacing side); + boolean canConnectNode(Direction side); } diff --git a/src/main/java/li/cil/oc/api/network/SidedEnvironment.java b/src/main/java/li/cil/oc/api/network/SidedEnvironment.java index 1257100430..509e56ed54 100644 --- a/src/main/java/li/cil/oc/api/network/SidedEnvironment.java +++ b/src/main/java/li/cil/oc/api/network/SidedEnvironment.java @@ -1,9 +1,9 @@ package li.cil.oc.api.network; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.Direction; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; /** * This interface is like {@link net.minecraft.inventory.ISidedInventory} is to @@ -32,7 +32,7 @@ public interface SidedEnvironment { * @return the node for the specified side. * @see li.cil.oc.api.network.Environment#node */ - Node sidedNode(EnumFacing side); + Node sidedNode(Direction side); /** * Whether the environment provides a node to connect to on the specified @@ -50,6 +50,6 @@ public interface SidedEnvironment { * @param side the side to check for. * @return whether the environment provides a node for the specified side. */ - @SideOnly(Side.CLIENT) - boolean canConnect(EnumFacing side); + @OnlyIn(Dist.CLIENT) + boolean canConnect(Direction side); } diff --git a/src/main/java/li/cil/oc/api/network/SimpleComponent.java b/src/main/java/li/cil/oc/api/network/SimpleComponent.java deleted file mode 100644 index 7c5d10de3f..0000000000 --- a/src/main/java/li/cil/oc/api/network/SimpleComponent.java +++ /dev/null @@ -1,114 +0,0 @@ -package li.cil.oc.api.network; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This interface can be used to easily convert tile entities to components, - * without having to implement {@link li.cil.oc.api.network.Environment} - * themselves. The simple implementation will provide no access to OC's internal - * component network, since you won't have access to the node representing the - * tile entity. Use this only for simple cases, where you want to expose a - * couple of methods to the programs running computers. - *

    - * This is an interface instead of an annotation, to allow stripping via the - * ever so handy {@link net.minecraftforge.fml.common.Optional} annotation, - * meaning there will be no strong dependency on OpenComputers. - *

    - * Classes implementing this interface will be expanded with the methods - * required for them to function as native block components (say, like the - * screen or keyboard). This means functions in the Environment - * interface have to created using a class transformer. If any of the methods - * already exist, this will fail! If things don't work, check your logs, first. - *

    - * To expose methods to OC, tag them with {@link li.cil.oc.api.machine.Callback} - * and have them use the according signature (see the documentation on the - * Callback annotation). - *

    - * Alternatively, implement {@link li.cil.oc.api.network.ManagedPeripheral} in - * addition to this interface, to make methods available ComputerCraft style. - *

    - * So, in short: - *

    - *

    - * For example: - *

    - *     {@literal @}Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers")
    - *     public class TileEntityMyFancyThing extends TileEntity
    - *            implements SimpleComponent
    - *     {
    - *         {@literal @}Override
    - *         public String getComponentName() {
    - *             return "fancy_thing";
    - *         }
    - *
    - *         {@literal @}Callback
    - *         {@literal @}Optional.Method(modid = "OpenComputers")
    - *         public Object[] greet(Context context, Arguments args) {
    - *             return new Object[]{String.format("Hello, %s!", args.checkString(0))};
    - *         }
    - *     }
    - * 
    - * Using the alternative method to provide methods: - *
    - *     {@literal @}Optional.InterfaceList({
    - *         {@literal @}Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "OpenComputers"),
    - *         {@literal @}Optional.Interface(iface = "li.cil.oc.api.network.ManagedPeripheral", modid = "OpenComputers")
    - *     })
    - *     public class TileEntityMyFancyThing extends TileEntity
    - *            implements SimpleComponent, ManagedPeripheral
    - *     {
    - *         {@literal @}Override
    - *         public String getComponentName() {
    - *             return "fancy_thing";
    - *         }
    - *
    - *         public String[] methods() {
    - *             return new String[] {"greet"};
    - *         }
    - *
    - *         {@literal @}Optional.Method(modid = "OpenComputers")
    - *         public Object[] invoke(String method, Context context, Arguments args) {
    - *             if ("greet".equals(method)) {
    - *                 return new Object[]{String.format("Hello, %s!", args.checkString(0))};
    - *             } else {
    - *                 throw new NoSuchMethodException();
    - *             }
    - *         }
    - *     }
    - * 
    - */ -public interface SimpleComponent { - /** - * The name the component should be made available as. - *

    component.list() in Lua, for - * example. You'll want to make this short and descriptive. The convention - * for component names is: all lowercase, underscores where necessary. Good - * component names are for example: disk_drive, furnace, crafting_table. - * - * @return the component's name. - */ - String getComponentName(); - - /** - * Use this to skip logic injection for the class this is implemented by. - *

    - * For example, if you have a class transformer that injects logic from a - * template class into your actual tile entities, OC's class transformer - * would complain when it finds the interface on the template class. That - * warning can be suppressed by using this annotation on the template. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - @interface SkipInjection { - } -} diff --git a/src/main/java/li/cil/oc/api/network/package-info.java b/src/main/java/li/cil/oc/api/network/package-info.java index 7fa496cdd0..6dbef6b188 100644 --- a/src/main/java/li/cil/oc/api/network/package-info.java +++ b/src/main/java/li/cil/oc/api/network/package-info.java @@ -4,10 +4,6 @@ * This mainly involves the (purely server-side!) network that is spanned over * all of OpenComputers' components, including blocks and items alike. */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|network", - apiVersion = API.VERSION) package li.cil.oc.api.network; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/package-info.java b/src/main/java/li/cil/oc/api/package-info.java index 502aa3781b..f9dae02d67 100644 --- a/src/main/java/li/cil/oc/api/package-info.java +++ b/src/main/java/li/cil/oc/api/package-info.java @@ -15,7 +15,7 @@ * Note that for tile entities you implement yourself, you will not have to * provide a driver, as long as you implement the necessary interface: * {@link li.cil.oc.api.network.Environment} and call {@link li.cil.oc.api.Network#joinOrCreateNetwork(net.minecraft.tileentity.TileEntity)} - * in the first updateEntity() call. For items that should be installed + * in the first tick() call. For items that should be installed * in a computer you will always have to provide a driver. * *

    The {@link li.cil.oc.api.FileSystem} API
    @@ -34,8 +34,4 @@ * * */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|core", - apiVersion = API.VERSION) package li.cil.oc.api; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/api/prefab/AbstractBehavior.java b/src/main/java/li/cil/oc/api/prefab/AbstractBehavior.java index ea1ad4bb9c..19429a0360 100644 --- a/src/main/java/li/cil/oc/api/prefab/AbstractBehavior.java +++ b/src/main/java/li/cil/oc/api/prefab/AbstractBehavior.java @@ -2,7 +2,7 @@ import li.cil.oc.api.nanomachines.Behavior; import li.cil.oc.api.nanomachines.DisableReason; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; /** * Base class for behaviors, mostly useful to have less cluttered classes when @@ -14,7 +14,7 @@ public abstract class AbstractBehavior implements Behavior { /** * The player this behavior was created for. */ - public final EntityPlayer player; + public final PlayerEntity player; /** * Pass along the player the behavior was created for here to have it stored @@ -22,7 +22,7 @@ public abstract class AbstractBehavior implements Behavior { * * @param player the player the behavior was created for. */ - protected AbstractBehavior(EntityPlayer player) { + protected AbstractBehavior(PlayerEntity player) { this.player = player; } diff --git a/src/main/java/li/cil/oc/api/prefab/AbstractManagedEnvironment.java b/src/main/java/li/cil/oc/api/prefab/AbstractManagedEnvironment.java index cb6c39145e..010668196b 100644 --- a/src/main/java/li/cil/oc/api/prefab/AbstractManagedEnvironment.java +++ b/src/main/java/li/cil/oc/api/prefab/AbstractManagedEnvironment.java @@ -3,7 +3,7 @@ import li.cil.oc.api.network.ManagedEnvironment; import li.cil.oc.api.network.Message; import li.cil.oc.api.network.Node; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; /** * Simple base implementation of the ManagedEnvironment interface, so @@ -46,14 +46,14 @@ public void onMessage(final Message message) { } @Override - public void load(final NBTTagCompound nbt) { + public void loadData(final CompoundNBT nbt) { if (node() != null) { - node().load(nbt.getCompoundTag(NODE_TAG)); + node().loadData(nbt.getCompound(NODE_TAG)); } } @Override - public void save(final NBTTagCompound nbt) { + public void saveData(final CompoundNBT nbt) { if (node() != null) { // Force joining a network when saving and we're not in one yet, so that // the address is embedded in the saved data that gets sent to the client, @@ -62,15 +62,15 @@ public void save(final NBTTagCompound nbt) { if (node().address() == null) { li.cil.oc.api.Network.joinNewNetwork(node()); - final NBTTagCompound nodeTag = new NBTTagCompound(); - node().save(nodeTag); - nbt.setTag(NODE_TAG, nodeTag); + final CompoundNBT nodeTag = new CompoundNBT(); + node().saveData(nodeTag); + nbt.put(NODE_TAG, nodeTag); node().remove(); } else { - final NBTTagCompound nodeTag = new NBTTagCompound(); - node().save(nodeTag); - nbt.setTag(NODE_TAG, nodeTag); + final CompoundNBT nodeTag = new CompoundNBT(); + node().saveData(nodeTag); + nbt.put(NODE_TAG, nodeTag); } } } diff --git a/src/main/java/li/cil/oc/api/prefab/AbstractProvider.java b/src/main/java/li/cil/oc/api/prefab/AbstractProvider.java index 9f03938353..58ca1b8597 100644 --- a/src/main/java/li/cil/oc/api/prefab/AbstractProvider.java +++ b/src/main/java/li/cil/oc/api/prefab/AbstractProvider.java @@ -2,8 +2,8 @@ import li.cil.oc.api.nanomachines.Behavior; import li.cil.oc.api.nanomachines.BehaviorProvider; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.CompoundNBT; /** * Example base implementation of nanomachine behavior provider. @@ -38,7 +38,7 @@ protected AbstractProvider(String id) { * @param behavior the behavior to persist. * @param nbt the NBT tag to persist it to. */ - protected void writeBehaviorToNBT(Behavior behavior, NBTTagCompound nbt) { + protected void writeBehaviorToNBT(Behavior behavior, CompoundNBT nbt) { } /** @@ -51,20 +51,20 @@ protected void writeBehaviorToNBT(Behavior behavior, NBTTagCompound nbt) { * @param nbt the NBT tag to load restore the behavior from. * @return the restored behavior. */ - protected abstract Behavior readBehaviorFromNBT(EntityPlayer player, NBTTagCompound nbt); + protected abstract Behavior readBehaviorFromNBT(PlayerEntity player, CompoundNBT nbt); // ----------------------------------------------------------------------- // @Override - public NBTTagCompound writeToNBT(Behavior behavior) { - NBTTagCompound nbt = new NBTTagCompound(); - nbt.setString("provider", id); + public CompoundNBT save(Behavior behavior) { + CompoundNBT nbt = new CompoundNBT(); + nbt.putString("provider", id); writeBehaviorToNBT(behavior, nbt); return nbt; } @Override - public Behavior readFromNBT(EntityPlayer player, NBTTagCompound nbt) { + public Behavior load(PlayerEntity player, CompoundNBT nbt) { if (id.equals(nbt.getString("provider"))) { return readBehaviorFromNBT(player, nbt); } else { diff --git a/src/main/java/li/cil/oc/api/prefab/AbstractValue.java b/src/main/java/li/cil/oc/api/prefab/AbstractValue.java index 7d686b5df6..d0c8261808 100644 --- a/src/main/java/li/cil/oc/api/prefab/AbstractValue.java +++ b/src/main/java/li/cil/oc/api/prefab/AbstractValue.java @@ -3,7 +3,7 @@ import li.cil.oc.api.machine.Arguments; import li.cil.oc.api.machine.Context; import li.cil.oc.api.machine.Value; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; /** * Basic implementation for the Value interface. @@ -28,10 +28,10 @@ public void dispose(Context context) { } @Override - public void load(NBTTagCompound nbt) { + public void loadData(CompoundNBT nbt) { } @Override - public void save(NBTTagCompound nbt) { + public void saveData(CompoundNBT nbt) { } } diff --git a/src/main/java/li/cil/oc/api/prefab/DriverItem.java b/src/main/java/li/cil/oc/api/prefab/DriverItem.java index e44e4b7797..c111035ec9 100644 --- a/src/main/java/li/cil/oc/api/prefab/DriverItem.java +++ b/src/main/java/li/cil/oc/api/prefab/DriverItem.java @@ -2,7 +2,7 @@ import li.cil.oc.api.network.EnvironmentHost; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.CompoundNBT; /** * If you wish to create item components such as the network card or hard drives @@ -30,7 +30,7 @@ protected DriverItem(final ItemStack... items) { public boolean worksWith(final ItemStack stack) { if (!stack.isEmpty()) { for (ItemStack item : items) { - if (!item.isEmpty() && item.isItemEqual(stack)) { + if (!item.isEmpty() && item.sameItem(stack)) { return true; } } @@ -44,17 +44,14 @@ public int tier(final ItemStack stack) { } @Override - public NBTTagCompound dataTag(final ItemStack stack) { - if (!stack.hasTagCompound()) { - stack.setTagCompound(new NBTTagCompound()); - } - final NBTTagCompound nbt = stack.getTagCompound(); + public CompoundNBT dataTag(final ItemStack stack) { + final CompoundNBT nbt = stack.getOrCreateTag(); // This is the suggested key under which to store item component data. // You are free to change this as you please. - if (!nbt.hasKey("oc:data")) { - nbt.setTag("oc:data", new NBTTagCompound()); + if (!nbt.contains("oc:data")) { + nbt.put("oc:data", new CompoundNBT()); } - return nbt.getCompoundTag("oc:data"); + return nbt.getCompound("oc:data"); } // Convenience methods provided for HostAware drivers. diff --git a/src/main/java/li/cil/oc/api/prefab/DriverSidedBlock.java b/src/main/java/li/cil/oc/api/prefab/DriverSidedBlock.java index 40ca7f1931..079d372630 100644 --- a/src/main/java/li/cil/oc/api/prefab/DriverSidedBlock.java +++ b/src/main/java/li/cil/oc/api/prefab/DriverSidedBlock.java @@ -1,14 +1,10 @@ package li.cil.oc.api.prefab; import li.cil.oc.api.driver.DriverBlock; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; +import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.world.World; -import net.minecraftforge.oredict.OreDictionary; /** * If you wish to create a block component for a third-party block, i.e. a block @@ -22,36 +18,24 @@ * You still have to provide the implementation for creating its environment, if * any. *

    - * To limit sidedness, I recommend overriding {@link #worksWith(World, BlockPos, EnumFacing)} + * To limit sidedness, I recommend overriding {@link #worksWith(World, BlockPos, Direction)} * and calling super.worksWith in addition to the side check. * * @see li.cil.oc.api.network.ManagedEnvironment */ @SuppressWarnings("UnusedDeclaration") public abstract class DriverSidedBlock implements DriverBlock { - protected final ItemStack[] blocks; + protected final BlockState[] blocks; - protected DriverSidedBlock(final ItemStack... blocks) { + protected DriverSidedBlock(final BlockState... blocks) { this.blocks = blocks.clone(); } @Override - public boolean worksWith(final World world, final BlockPos pos, final EnumFacing side) { - final IBlockState state = world.getBlockState(pos); - final Block block = state.getBlock(); - return worksWith(block, block.getMetaFromState(state)); - } - - protected boolean worksWith(final Block referenceBlock, final int referenceMetadata) { - for (ItemStack stack : blocks) { - if (!stack.isEmpty() && stack.getItem() instanceof ItemBlock) { - final ItemBlock item = (ItemBlock) stack.getItem(); - final Block supportedBlock = item.getBlock(); - final int supportedMetadata = item.getMetadata(stack.getItemDamage()); - if (referenceBlock == supportedBlock && (referenceMetadata == supportedMetadata || stack.getItemDamage() == OreDictionary.WILDCARD_VALUE)) { - return true; - } - } + public boolean worksWith(final World world, final BlockPos pos, final Direction side) { + final BlockState state = world.getBlockState(pos); + for (BlockState block : blocks) { + if (block == state) return true; } return false; } diff --git a/src/main/java/li/cil/oc/api/prefab/DriverSidedTileEntity.java b/src/main/java/li/cil/oc/api/prefab/DriverSidedTileEntity.java index e17b3b0d86..9c40c7183a 100644 --- a/src/main/java/li/cil/oc/api/prefab/DriverSidedTileEntity.java +++ b/src/main/java/li/cil/oc/api/prefab/DriverSidedTileEntity.java @@ -3,25 +3,25 @@ import li.cil.oc.api.driver.DriverBlock; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.world.World; /** - * To limit sidedness, I recommend overriding {@link #worksWith(World, BlockPos, EnumFacing)} + * To limit sidedness, I recommend overriding {@link #worksWith(World, BlockPos, Direction)} * and calling super.worksWith in addition to the side check. */ public abstract class DriverSidedTileEntity implements DriverBlock { public abstract Class getTileEntityClass(); @Override - public boolean worksWith(final World world, final BlockPos pos, final EnumFacing side) { + public boolean worksWith(final World world, final BlockPos pos, final Direction side) { final Class filter = getTileEntityClass(); if (filter == null) { // This can happen if filter classes are deduced by reflection and // the class in question is not present. return false; } - final TileEntity tileEntity = world.getTileEntity(pos); + final TileEntity tileEntity = world.getBlockEntity(pos); return tileEntity != null && filter.isAssignableFrom(tileEntity.getClass()); } } diff --git a/src/main/java/li/cil/oc/api/prefab/ItemStackArrayValue.java b/src/main/java/li/cil/oc/api/prefab/ItemStackArrayValue.java index 883cc40b3c..e916a3d38f 100644 --- a/src/main/java/li/cil/oc/api/prefab/ItemStackArrayValue.java +++ b/src/main/java/li/cil/oc/api/prefab/ItemStackArrayValue.java @@ -4,9 +4,8 @@ import li.cil.oc.api.machine.Callback; import li.cil.oc.api.machine.Context; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; import java.util.HashMap; import java.util.TreeMap; @@ -16,8 +15,8 @@ public class ItemStackArrayValue extends AbstractValue { private ItemStack[] array = null; private int iteratorIndex; - private static final byte TAGLIST_ID = (new NBTTagList()).getId(); - private static final byte COMPOUND_ID = (new NBTTagCompound()).getId(); + private static final byte TAGLIST_ID = (new ListNBT()).getId(); + private static final byte COMPOUND_ID = (new CompoundNBT()).getId(); private static final String ARRAY_KEY = "Array"; private static final String INDEX_KEY = "Index"; @@ -70,43 +69,42 @@ public Object apply(Context context, Arguments arguments) { } @Override - public void load(NBTTagCompound nbt) { - if (nbt.hasKey(ARRAY_KEY, TAGLIST_ID)){ - NBTTagList tagList = nbt.getTagList(ARRAY_KEY,COMPOUND_ID); - this.array = new ItemStack[tagList.tagCount()]; - for (int i = 0; i < tagList.tagCount(); ++i){ - NBTTagCompound el = tagList.getCompoundTagAt(i); - if (el.hasNoTags()) + public void loadData(CompoundNBT nbt) { + if (nbt.contains(ARRAY_KEY, TAGLIST_ID)){ + ListNBT tagList = nbt.getList(ARRAY_KEY,COMPOUND_ID); + this.array = new ItemStack[tagList.size()]; + for (int i = 0; i < tagList.size(); ++i){ + CompoundNBT el = tagList.getCompound(i); + if (el.isEmpty()) this.array[i] = ItemStack.EMPTY; else - this.array[i] = new ItemStack(el); + this.array[i] = ItemStack.of(el); } } else { this.array = null; } - this.iteratorIndex = nbt.getInteger(INDEX_KEY); + this.iteratorIndex = nbt.getInt(INDEX_KEY); } @Override - public void save(NBTTagCompound nbt) { + public void saveData(CompoundNBT nbt) { - NBTTagCompound nullnbt = new NBTTagCompound(); + CompoundNBT nullnbt = new CompoundNBT(); if (this.array != null) { - NBTTagList nbttaglist = new NBTTagList(); + ListNBT nbttaglist = new ListNBT(); for (ItemStack stack : this.array) { if (stack != null) { - NBTBase nbttagcompound = stack.serializeNBT(); - nbttaglist.appendTag(nbttagcompound); + nbttaglist.add(stack.save(new CompoundNBT())); } else { - nbttaglist.appendTag(nullnbt); + nbttaglist.add(nullnbt); } } - nbt.setTag(ARRAY_KEY, nbttaglist); + nbt.put(ARRAY_KEY, nbttaglist); } - nbt.setInteger(INDEX_KEY, iteratorIndex); + nbt.putInt(INDEX_KEY, iteratorIndex); } @Callback(doc="function():nil -- Reset the iterator index so that the next call will return the first element.") diff --git a/src/main/java/li/cil/oc/api/prefab/ItemStackTabIconRenderer.java b/src/main/java/li/cil/oc/api/prefab/ItemStackTabIconRenderer.java index 5c42ff2142..2267a68968 100644 --- a/src/main/java/li/cil/oc/api/prefab/ItemStackTabIconRenderer.java +++ b/src/main/java/li/cil/oc/api/prefab/ItemStackTabIconRenderer.java @@ -1,13 +1,13 @@ package li.cil.oc.api.prefab; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import li.cil.oc.api.manual.TabIconRenderer; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.RenderHelper; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.lwjgl.opengl.GL13; /** * Simple implementation of a tab icon renderer using an item stack as its graphic. @@ -20,13 +20,15 @@ public ItemStackTabIconRenderer(ItemStack stack) { this.stack = stack; } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) @Override - public void render() { - GlStateManager.enableRescaleNormal(); - RenderHelper.enableGUIStandardItemLighting(); - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - Minecraft.getMinecraft().getRenderItem().renderItemAndEffectIntoGUI(stack, 0, 0); - RenderHelper.disableStandardItemLighting(); + public void render(MatrixStack matrix) { + // Translate manually because ItemRenderer generally can't take a MatrixStack. + RenderSystem.pushMatrix(); + RenderSystem.multMatrix(matrix.last().pose()); + RenderSystem.enableRescaleNormal(); + RenderSystem.glMultiTexCoord2f(GL13.GL_TEXTURE1, 240, 240); + Minecraft.getInstance().getItemRenderer().renderAndDecorateItem(stack, 0, 0); + RenderSystem.popMatrix(); } } diff --git a/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java b/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java index 44d5efe680..2113b8f4fb 100644 --- a/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java +++ b/src/main/java/li/cil/oc/api/prefab/ResourceContentProvider.java @@ -40,10 +40,11 @@ public ResourceContentProvider(String resourceDomain) { @Override public Iterable getContent(String path) { - final ResourceLocation location = new ResourceLocation(resourceDomain, basePath + (path.startsWith("/") ? path.substring(1) : path)); + final String resourcePath = basePath + (path.startsWith("/") ? path.substring(1) : path); + final ResourceLocation location = new ResourceLocation(resourceDomain, resourcePath.toLowerCase()); InputStream is = null; try { - is = Minecraft.getMinecraft().getResourceManager().getResource(location).getInputStream(); + is = Minecraft.getInstance().getResourceManager().getResource(location).getInputStream(); final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charsets.UTF_8)); final ArrayList lines = new ArrayList(); String line; diff --git a/src/main/java/li/cil/oc/api/prefab/TextureTabIconRenderer.java b/src/main/java/li/cil/oc/api/prefab/TextureTabIconRenderer.java index 3b7f45eff4..db63f084c8 100644 --- a/src/main/java/li/cil/oc/api/prefab/TextureTabIconRenderer.java +++ b/src/main/java/li/cil/oc/api/prefab/TextureTabIconRenderer.java @@ -1,14 +1,15 @@ package li.cil.oc.api.prefab; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import li.cil.oc.api.manual.TabIconRenderer; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import org.lwjgl.opengl.GL11; /** @@ -23,17 +24,16 @@ public TextureTabIconRenderer(ResourceLocation location) { } @Override - @SideOnly(Side.CLIENT) - public void render() { - Minecraft.getMinecraft().getTextureManager().bindTexture(location); - GlStateManager.bindTexture(Minecraft.getMinecraft().getTextureManager().getTexture(location).getGlTextureId()); + @OnlyIn(Dist.CLIENT) + public void render(MatrixStack stack) { + Minecraft.getInstance().getTextureManager().bind(location); final Tessellator t = Tessellator.getInstance(); - final BufferBuilder r = t.getBuffer(); + final BufferBuilder r = t.getBuilder(); r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - r.pos(0, 16, 0).tex(0, 1).endVertex(); - r.pos(16, 16, 0).tex(1, 1).endVertex(); - r.pos(16, 0, 0).tex(1, 0).endVertex(); - r.pos(0, 0, 0).tex(0, 0).endVertex(); - t.draw(); + r.vertex(stack.last().pose(), 0, 16, 0).uv(0, 1).endVertex(); + r.vertex(stack.last().pose(), 16, 16, 0).uv(1, 1).endVertex(); + r.vertex(stack.last().pose(), 16, 0, 0).uv(1, 0).endVertex(); + r.vertex(stack.last().pose(), 0, 0, 0).uv(0, 0).endVertex(); + t.end(); } } diff --git a/src/main/java/li/cil/oc/api/prefab/TileEntityEnvironment.java b/src/main/java/li/cil/oc/api/prefab/TileEntityEnvironment.java index 010fd82423..ac1a15ad31 100644 --- a/src/main/java/li/cil/oc/api/prefab/TileEntityEnvironment.java +++ b/src/main/java/li/cil/oc/api/prefab/TileEntityEnvironment.java @@ -5,8 +5,10 @@ import li.cil.oc.api.network.Message; import li.cil.oc.api.network.Node; import li.cil.oc.api.network.Visibility; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityType; /** * TileEntities can implement the {@link li.cil.oc.api.network.Environment} @@ -58,6 +60,10 @@ public abstract class TileEntityEnvironment extends TileEntity implements Enviro protected Node node; // ----------------------------------------------------------------------- // + + public TileEntityEnvironment(TileEntityType type) { + super(type); + } @Override public Node node() { @@ -67,7 +73,7 @@ public Node node() { @Override public void onConnect(final Node node) { // This is called when the call to Network.joinOrCreateNetwork(this) in - // updateEntity was successful, in which case `node == this`. + // tick was successful, in which case `node == this`. // This is also called for any other node that gets connected to the // network our node is in, in which case `node` is the added node. // If our node is added to an existing network, this is called for each @@ -77,8 +83,8 @@ public void onConnect(final Node node) { @Override public void onDisconnect(final Node node) { // This is called when this node is removed from its network when the - // tile entity is removed from the world (see onChunkUnload() and - // invalidate()), in which case `node == this`. + // tile entity is removed from the world (see onChunkUnloaded() and + // setRemoved()), in which case `node == this`. // This is also called for each other node that gets removed from the // network our node is in, in which case `node` is the removed node. // If a net-split occurs this is called for each node that is no longer @@ -100,16 +106,16 @@ public void onLoad() { } @Override - public void onChunkUnload() { - super.onChunkUnload(); + public void onChunkUnloaded() { + super.onChunkUnloaded(); // Make sure to remove the node from its network when its environment, // meaning this tile entity, gets unloaded. if (node != null) node.remove(); } @Override - public void invalidate() { - super.invalidate(); + public void setRemoved() { + super.setRemoved(); // Make sure to remove the node from its network when its environment, // meaning this tile entity, gets unloaded. if (node != null) node.remove(); @@ -118,8 +124,8 @@ public void invalidate() { // ----------------------------------------------------------------------- // @Override - public void readFromNBT(final NBTTagCompound nbt) { - super.readFromNBT(nbt); + public void load(final BlockState state, final CompoundNBT nbt) { + super.load(state, nbt); // The host check may be superfluous for you. It's just there to allow // some special cases, where getNode() returns some node managed by // some other instance (for example when you have multiple internal @@ -129,18 +135,18 @@ public void readFromNBT(final NBTTagCompound nbt) { // to continue working without interruption across loads. If the // node is a power connector this is also required to restore the // internal energy buffer of the node. - node.load(nbt.getCompoundTag(TAG_NODE)); + node.loadData(nbt.getCompound(TAG_NODE)); } } @Override - public NBTTagCompound writeToNBT(final NBTTagCompound nbt) { - super.writeToNBT(nbt); - // See readFromNBT() regarding host check. + public CompoundNBT save(final CompoundNBT nbt) { + super.save(nbt); + // See load() regarding host check. if (node != null && node.host() == this) { - final NBTTagCompound nodeNbt = new NBTTagCompound(); - node.save(nodeNbt); - nbt.setTag(TAG_NODE, nodeNbt); + final CompoundNBT nodeNbt = new CompoundNBT(); + node.saveData(nodeNbt); + nbt.put(TAG_NODE, nodeNbt); } return nbt; } diff --git a/src/main/java/li/cil/oc/api/prefab/TileEntitySidedEnvironment.java b/src/main/java/li/cil/oc/api/prefab/TileEntitySidedEnvironment.java index c3d878d9ed..953685a04f 100644 --- a/src/main/java/li/cil/oc/api/prefab/TileEntitySidedEnvironment.java +++ b/src/main/java/li/cil/oc/api/prefab/TileEntitySidedEnvironment.java @@ -3,10 +3,12 @@ import li.cil.oc.api.Network; import li.cil.oc.api.network.Node; import li.cil.oc.api.network.SidedEnvironment; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.ITickable; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; /** * TileEntities can implement the {@link li.cil.oc.api.network.SidedEnvironment} @@ -19,11 +21,11 @@ * network as an index structure to find other nodes connected to them. */ @SuppressWarnings("UnusedDeclaration") -public abstract class TileEntitySidedEnvironment extends TileEntity implements SidedEnvironment, ITickable { +public abstract class TileEntitySidedEnvironment extends TileEntity implements SidedEnvironment, ITickableTileEntity { // See constructor. protected Node[] nodes = new Node[6]; - // See updateEntity(). + // See tick(). protected boolean addedToNetwork = false; /** @@ -60,7 +62,8 @@ public abstract class TileEntitySidedEnvironment extends TileEntity implements S * .create(), ...); * */ - protected TileEntitySidedEnvironment(final Node... nodes) { + protected TileEntitySidedEnvironment(TileEntityType type, final Node... nodes) { + super(type); System.arraycopy(nodes, 0, this.nodes, 0, Math.min(nodes.length, this.nodes.length)); } @@ -72,17 +75,17 @@ protected TileEntitySidedEnvironment(final Node... nodes) { // exists for a side won't work on the client. @Override - public Node sidedNode(final EnumFacing side) { + public Node sidedNode(final Direction side) { return nodes[side.ordinal()]; } // ----------------------------------------------------------------------- // @Override - public void update() { + public void tick() { // On the first update, try to add our node to nearby networks. We do - // this in the update logic, not in validate() because we need to access - // neighboring tile entities, which isn't possible in validate(). + // this in the update logic, not in clearRemoved() because we need to access + // neighboring tile entities, which isn't possible in clearRemoved(). // We could alternatively check node != null && node.network() == null, // but this has somewhat better performance, and makes it clearer. if (!addedToNetwork) { @@ -94,8 +97,8 @@ public void update() { } @Override - public void onChunkUnload() { - super.onChunkUnload(); + public void onChunkUnloaded() { + super.onChunkUnloaded(); // Make sure to remove the node from its network when its environment, // meaning this tile entity, gets unloaded. for (Node node : nodes) { @@ -104,8 +107,8 @@ public void onChunkUnload() { } @Override - public void invalidate() { - super.invalidate(); + public void setRemoved() { + super.setRemoved(); // Make sure to remove the node from its network when its environment, // meaning this tile entity, gets unloaded. for (Node node : nodes) { @@ -116,8 +119,8 @@ public void invalidate() { // ----------------------------------------------------------------------- // @Override - public void readFromNBT(final NBTTagCompound nbt) { - super.readFromNBT(nbt); + public void load(final BlockState state, final CompoundNBT nbt) { + super.load(state, nbt); int index = 0; for (Node node : nodes) { // The host check may be superfluous for you. It's just there to allow @@ -129,22 +132,22 @@ public void readFromNBT(final NBTTagCompound nbt) { // to continue working without interruption across loads. If the // node is a power connector this is also required to restore the // internal energy buffer of the node. - node.load(nbt.getCompoundTag("oc:node" + index)); + node.loadData(nbt.getCompound("oc:node" + index)); } ++index; } } @Override - public NBTTagCompound writeToNBT(NBTTagCompound nbt) { - super.writeToNBT(nbt); + public CompoundNBT save(CompoundNBT nbt) { + super.save(nbt); int index = 0; for (Node node : nodes) { - // See readFromNBT() regarding host check. + // See load() regarding host check. if (node != null && node.host() == this) { - final NBTTagCompound nodeNbt = new NBTTagCompound(); - node.save(nodeNbt); - nbt.setTag("oc:node" + index, nodeNbt); + final CompoundNBT nodeNbt = new CompoundNBT(); + node.saveData(nodeNbt); + nbt.put("oc:node" + index, nodeNbt); } ++index; } diff --git a/src/main/java/li/cil/oc/api/prefab/package-info.java b/src/main/java/li/cil/oc/api/prefab/package-info.java index a28cc87fba..8fb8970f61 100644 --- a/src/main/java/li/cil/oc/api/prefab/package-info.java +++ b/src/main/java/li/cil/oc/api/prefab/package-info.java @@ -7,10 +7,6 @@ * while leaving them in the same package with the same name and then ship them * with your mod! */ -@net.minecraftforge.fml.common.API( - owner = API.ID_OWNER, - provides = "opencomputersapi|prefab", - apiVersion = API.VERSION) package li.cil.oc.api.prefab; import li.cil.oc.api.API; \ No newline at end of file diff --git a/src/main/java/li/cil/oc/common/asm/SimpleComponentTickHandler.java b/src/main/java/li/cil/oc/common/asm/SimpleComponentTickHandler.java deleted file mode 100644 index 1bfca877f6..0000000000 --- a/src/main/java/li/cil/oc/common/asm/SimpleComponentTickHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package li.cil.oc.common.asm; - -import li.cil.oc.api.Network; -import li.cil.oc.util.SideTracker; -import net.minecraft.tileentity.TileEntity; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.ArrayList; - -// This class is used for adding simple components to the component network. -// It is triggered from a validate call, and executed in the next update tick. -public final class SimpleComponentTickHandler { - private static final Logger log = LogManager.getLogger("OpenComputers"); - - public static final ArrayList pending = new java.util.ArrayList(); - - public static final SimpleComponentTickHandler Instance = new SimpleComponentTickHandler(); - - private SimpleComponentTickHandler() { - } - - public static void schedule(final TileEntity tileEntity) { - if (SideTracker.isServer()) { - synchronized (pending) { - pending.add(new Runnable() { - @Override - public void run() { - Network.joinOrCreateNetwork(tileEntity); - } - }); - } - } - } - - @SubscribeEvent - public void onTick(TickEvent.ServerTickEvent e) { - if (e.phase == TickEvent.Phase.START) { - final Runnable[] adds; - synchronized (pending) { - adds = pending.toArray(new Runnable[pending.size()]); - pending.clear(); - } - for (Runnable runnable : adds) { - try { - runnable.run(); - } catch (Throwable t) { - log.warn("Error in scheduled tick action.", t); - } - } - } - } -} diff --git a/src/main/java/li/cil/oc/common/asm/template/SimpleComponentImpl.java b/src/main/java/li/cil/oc/common/asm/template/SimpleComponentImpl.java deleted file mode 100644 index a73aa62056..0000000000 --- a/src/main/java/li/cil/oc/common/asm/template/SimpleComponentImpl.java +++ /dev/null @@ -1,28 +0,0 @@ -package li.cil.oc.common.asm.template; - -import li.cil.oc.api.network.Environment; -import li.cil.oc.api.network.SimpleComponent; -import net.minecraft.nbt.NBTTagCompound; - -/** - * This interface defines the names to which existing or placeholders for - * existing methods will be moved. This allows transparent injection of our - * functionality, i.e. existing validate() etc. methods will be called as - * if we didn't inject our code. - *

    - * Yes, the names are not "conventional", but that is by design, to avoid - * naming collisions. - */ -public interface SimpleComponentImpl extends Environment, SimpleComponent { - public static final String PostFix = "_OpenComputers"; - - void validate_OpenComputers(); - - void invalidate_OpenComputers(); - - void onChunkUnload_OpenComputers(); - - void readFromNBT_OpenComputers(NBTTagCompound nbt); - - NBTTagCompound writeToNBT_OpenComputers(NBTTagCompound nbt); -} diff --git a/src/main/java/li/cil/oc/common/asm/template/SimpleEnvironment.java b/src/main/java/li/cil/oc/common/asm/template/SimpleEnvironment.java deleted file mode 100644 index c866b4bc48..0000000000 --- a/src/main/java/li/cil/oc/common/asm/template/SimpleEnvironment.java +++ /dev/null @@ -1,85 +0,0 @@ -package li.cil.oc.common.asm.template; - -import li.cil.oc.api.network.Message; -import li.cil.oc.api.network.Node; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; - -// This is a template implementation of methods injected into classes that are -// marked for component functionality. These methods will be copied into tile -// entities marked as simple components as necessary by the class transformer. -@SuppressWarnings("unused") -public abstract class SimpleEnvironment extends TileEntity implements SimpleComponentImpl { - @Override - public Node node() { - return StaticSimpleEnvironment.node(this); - } - - @Override - public void onConnect(Node node) { - } - - @Override - public void onDisconnect(Node node) { - } - - @Override - public void onMessage(Message message) { - } - - // These are always injected, after possibly existing versions have been - // renamed to the below variants from the SimpleComponentImpl interface. - // This allows transparent wrapping of already present implementations, - // instead of plain overwriting them. - - @Override - public void validate() { - StaticSimpleEnvironment.validate(this); - } - - @Override - public void invalidate() { - StaticSimpleEnvironment.invalidate(this); - } - - @Override - public void onChunkUnload() { - StaticSimpleEnvironment.onChunkUnload(this); - } - - @Override - public void readFromNBT(NBTTagCompound nbt) { - StaticSimpleEnvironment.readFromNBT(this, nbt); - } - - @Override - public NBTTagCompound writeToNBT(NBTTagCompound nbt) { - return StaticSimpleEnvironment.writeToNBT(this, nbt); - } - - // The following methods are only injected if their real versions do not - // exist in the class we're injecting into. Otherwise their real versions - // are renamed to these variations, which simply delegate to the parent. - // This way they are always guaranteed to be present, so we can simply call - // them through an interface, and need no runtime reflection. - - public void validate_OpenComputers() { - super.validate(); - } - - public void invalidate_OpenComputers() { - super.invalidate(); - } - - public void onChunkUnload_OpenComputers() { - super.onChunkUnload(); - } - - public void readFromNBT_OpenComputers(NBTTagCompound nbt) { - super.readFromNBT(nbt); - } - - public NBTTagCompound writeToNBT_OpenComputers(NBTTagCompound nbt) { - return super.writeToNBT(nbt); - } -} diff --git a/src/main/java/li/cil/oc/common/asm/template/StaticSimpleEnvironment.java b/src/main/java/li/cil/oc/common/asm/template/StaticSimpleEnvironment.java deleted file mode 100644 index 82d2b81d82..0000000000 --- a/src/main/java/li/cil/oc/common/asm/template/StaticSimpleEnvironment.java +++ /dev/null @@ -1,91 +0,0 @@ -package li.cil.oc.common.asm.template; - -import com.google.common.base.Strings; -import li.cil.oc.api.Network; -import li.cil.oc.api.network.Environment; -import li.cil.oc.api.network.Node; -import li.cil.oc.api.network.Visibility; -import li.cil.oc.common.asm.SimpleComponentTickHandler; -import li.cil.oc.util.SideTracker; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.tileentity.TileEntity; - -import java.util.HashMap; -import java.util.Map; - -// This class contains actual implementations of methods injected into tile -// entities marked as simple components using the SimpleComponent interface. -// They are called from the template methods, to keep the injected methods -// minimal, instruction wise, and avoid weird dependencies making the injection -// unnecessarily complicated. -public final class StaticSimpleEnvironment { - private StaticSimpleEnvironment() { - } - - private static final Map nodes = new HashMap(); - - public static Node node(final SimpleComponentImpl self) { - // Save ourselves the lookup time in the hash map and avoid mixing in - // client side tile entities into the map when in single player. - if (SideTracker.isClient()) { - return null; - } - final String name = self.getComponentName(); - // If the name is null (or empty) this indicates we don't have a valid - // component right now, so if we have a node we kill it. - if (Strings.isNullOrEmpty(name)) { - final Node node = nodes.remove(self); - if (node != null) { - node.remove(); - } - } else if (!nodes.containsKey(self)) { - nodes.put(self, Network. - newNode(self, Visibility.Network). - withComponent(name). - create()); - } - return nodes.get(self); - } - - public static void validate(final SimpleComponentImpl self) { - self.validate_OpenComputers(); - SimpleComponentTickHandler.schedule((TileEntity) self); - } - - public static void invalidate(final SimpleComponentImpl self) { - self.invalidate_OpenComputers(); - final Node node = node(self); - if (node != null) { - node.remove(); - nodes.remove(self); - } - } - - public static void onChunkUnload(final SimpleComponentImpl self) { - self.onChunkUnload_OpenComputers(); - final Node node = node(self); - if (node != null) { - node.remove(); - nodes.remove(self); - } - } - - public static void readFromNBT(final SimpleComponentImpl self, NBTTagCompound nbt) { - self.readFromNBT_OpenComputers(nbt); - final Node node = node(self); - if (node != null) { - node.load(nbt.getCompoundTag("oc:node")); - } - } - - public static NBTTagCompound writeToNBT(final SimpleComponentImpl self, NBTTagCompound nbt) { - nbt = self.writeToNBT_OpenComputers(nbt); - final Node node = node(self); - if (node != null) { - final NBTTagCompound nodeNbt = new NBTTagCompound(); - node.save(nodeNbt); - nbt.setTag("oc:node", nodeNbt); - } - return nbt; - } -} diff --git a/src/main/java/li/cil/oc/integration/charset/CapabilitiesCharset.java b/src/main/java/li/cil/oc/integration/charset/CapabilitiesCharset.java deleted file mode 100644 index 32be1c7df9..0000000000 --- a/src/main/java/li/cil/oc/integration/charset/CapabilitiesCharset.java +++ /dev/null @@ -1,19 +0,0 @@ -package li.cil.oc.integration.charset; - -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.CapabilityInject; -import pl.asie.charset.api.wires.IBundledEmitter; -import pl.asie.charset.api.wires.IBundledReceiver; -import pl.asie.charset.api.wires.IRedstoneEmitter; -import pl.asie.charset.api.wires.IRedstoneReceiver; - -public final class CapabilitiesCharset { - @CapabilityInject(IBundledEmitter.class) - public static Capability BUNDLED_EMITTER; - @CapabilityInject(IBundledReceiver.class) - public static Capability BUNDLED_RECEIVER; - @CapabilityInject(IRedstoneEmitter.class) - public static Capability REDSTONE_EMITTER; - @CapabilityInject(IRedstoneReceiver.class) - public static Capability REDSTONE_RECEIVER; -} \ No newline at end of file diff --git a/src/main/java/li/cil/oc/util/SideTracker.java b/src/main/java/li/cil/oc/util/SideTracker.java index 1a0f302ee7..238826eb2e 100644 --- a/src/main/java/li/cil/oc/util/SideTracker.java +++ b/src/main/java/li/cil/oc/util/SideTracker.java @@ -1,19 +1,14 @@ package li.cil.oc.util; -import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.forgespi.Environment; +import net.minecraftforge.fml.common.thread.EffectiveSide; import java.util.Collections; import java.util.Set; public final class SideTracker { - private static final Set serverThreads = Collections.newSetFromMap(new java.util.WeakHashMap()); - - public static void addServerThread() { - serverThreads.add(Thread.currentThread()); - } - public static boolean isServer() { - return FMLCommonHandler.instance().getEffectiveSide().isServer() || serverThreads.contains(Thread.currentThread()); + return Environment.get().getDist().isDedicatedServer() || EffectiveSide.get().isServer(); } public static boolean isClient() { diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg new file mode 100644 index 0000000000..564c1daff7 --- /dev/null +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -0,0 +1,13 @@ + # OpenComputers access transformer config +public net.minecraft.block.PistonBlock func_176319_a(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/Direction;Z)Z # moveBlocks +public-f net.minecraft.entity.player.PlayerEntity field_71069_bz # inventoryMenu +public-f net.minecraft.entity.player.PlayerEntity field_71071_by # inventory +public net.minecraft.tileentity.AbstractFurnaceTileEntity field_214018_j # litTime +public net.minecraft.tileentity.AbstractFurnaceTileEntity field_214019_k # litDuration +public net.minecraft.tileentity.AbstractFurnaceTileEntity field_214020_l # cookingProgress +public net.minecraft.tileentity.AbstractFurnaceTileEntity field_214021_m # cookingTotalTime +public net.minecraft.tileentity.BeaconTileEntity field_146010_n # secondaryPower +public net.minecraft.tileentity.BeaconTileEntity field_146013_m # primaryPower +public net.minecraft.tileentity.BrewingStandTileEntity field_145946_k # brewTime +public net.minecraft.tileentity.SignTileEntity field_145915_a # messages +public net.minecraft.world.spawner.AbstractSpawner func_190895_g()Lnet/minecraft/util/ResourceLocation; # getEntityId diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000000..b043f05888 --- /dev/null +++ b/src/main/resources/META-INF/mods.toml @@ -0,0 +1,29 @@ +modLoader="scorge" +loaderVersion="[${sversion},)" +license="MIT, CC0 (see LICENSE)" +issueTrackerURL="https://github.com/MightyPirates/OpenComputers/issues" + +[[mods]] +modId="opencomputers" +entryClass="li.cil.oc.OpenComputers" +version="${version}" +displayName="OpenComputers" +displayURL="http://oc.cil.li/" +logoFile="pack.png" +credits="Inspired by a couple of other mods, most notably ComputerCraft." +authors="Sangar, Vexatos, payonel, magik6k, Lord Joda and Github Contributors" +description="This mod adds modular computers and robots that can be programmed in Lua." + +[[dependencies.opencomputers]] + modId="minecraft" + mandatory=true + versionRange="[${mcversion}]" + ordering="NONE" + side="BOTH" + +[[dependencies.opencomputers]] + modId="jei" + mandatory=false + versionRange="[7,)" + ordering="AFTER" + side="BOTH" diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/adapter.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/adapter.json deleted file mode 100644 index 039cc63217..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/adapter.json +++ /dev/null @@ -1,12 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/inventory.json", - "traits/powerAcceptor.json" - ], - "nbt": { - "blacklist": [ - "oc:adapter.blocks" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/assembler.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/assembler.json deleted file mode 100644 index 9db233b831..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/assembler.json +++ /dev/null @@ -1,12 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/inventory.json", - "traits/powerAcceptor.json" - ], - "nbt": { - "blacklist": [ - "oc:remaining" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/cable.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/cable.json deleted file mode 100644 index 2a5da92da9..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/cable.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["traits/environment.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/capacitor.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/capacitor.json deleted file mode 100644 index 2a5da92da9..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/capacitor.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["traits/environment.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/case.json deleted file mode 100644 index d0a7fe6c55..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case.json +++ /dev/null @@ -1,9 +0,0 @@ -[{ - "includes": [ - "traits/computer.json", - "traits/inventory.json", - "traits/powerAcceptor.json", - "traits/redstone.json", - "traits/rotatable.json" - ] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case1.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/case1.json deleted file mode 100644 index 5236537c8f..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case1.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["case.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case2.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/case2.json deleted file mode 100644 index 5236537c8f..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case2.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["case.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case3.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/case3.json deleted file mode 100644 index 5236537c8f..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/case3.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["case.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/caseCreative.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/caseCreative.json deleted file mode 100644 index 5236537c8f..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/caseCreative.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["case.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/charger.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/charger.json deleted file mode 100644 index 5c05e72697..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/charger.json +++ /dev/null @@ -1,16 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/inventory.json", - "traits/powerAcceptor.json", - "traits/redstone.json", - "traits/rotatable.json" - ], - "nbt": { - "blacklist": [ - "chargeSpeed", - "hasPower", - "invertSignal" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/disassembler.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/disassembler.json deleted file mode 100644 index 9ab51a0fc5..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/disassembler.json +++ /dev/null @@ -1,14 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/inventory.json", - "traits/powerAcceptor.json" - ], - "nbt": { - "blacklist": [ - "oc:buffer", - "oc:queue", - "oc:total" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/diskDrive.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/diskDrive.json deleted file mode 100644 index 7a52c2ef3b..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/diskDrive.json +++ /dev/null @@ -1,7 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/inventory.json", - "traits/rotatable.json" - ] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/geolyzer.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/geolyzer.json deleted file mode 100644 index 2a5da92da9..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/geolyzer.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["traits/environment.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram.json deleted file mode 100644 index 5e40db6c34..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram.json +++ /dev/null @@ -1,7 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/externalData.json", - "traits/rotatable.json" - ] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram1.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram1.json deleted file mode 100644 index e7bedbd909..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram1.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["hologram.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram2.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram2.json deleted file mode 100644 index e7bedbd909..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/hologram2.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["hologram.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/keyboard.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/keyboard.json deleted file mode 100644 index a1a9760b28..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/keyboard.json +++ /dev/null @@ -1,8 +0,0 @@ -[{ - "includes": ["traits/rotatable.json"], - "nbt": { - "blacklist": [ - "oc:keyboard" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/microcontroller.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/microcontroller.json deleted file mode 100644 index de8fbc3846..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/microcontroller.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "includes": [ - "traits/computer.json", - "traits/hub.json", - "traits/inventory.json", - "traits/powerAcceptor.json", - "traits/redstone.json", - "traits/rotatable.json" - ], - "nbt": { - "blacklist": [ - "oc:info", - "oc:snooper", - "oc:componentNodes", - "oc:outputs" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/motionSensor.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/motionSensor.json deleted file mode 100644 index 2a5da92da9..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/motionSensor.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["traits/environment.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/netSplitter.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/netSplitter.json deleted file mode 100644 index 5c133025fa..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/netSplitter.json +++ /dev/null @@ -1,6 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/redstone.json" - ] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/powerConverter.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/powerConverter.json deleted file mode 100644 index 4b10cadc24..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/powerConverter.json +++ /dev/null @@ -1,6 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/powerAcceptor.json" - ] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/powerDistributor.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/powerDistributor.json deleted file mode 100644 index 0ce5d96fcc..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/powerDistributor.json +++ /dev/null @@ -1,7 +0,0 @@ -[{ - "nbt": { - "blacklist": [ - "oc:connector" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/printer.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/printer.json deleted file mode 100644 index 7c1dca4816..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/printer.json +++ /dev/null @@ -1,16 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/inventory.json" - ], - "nbt": { - "blacklist": [ - "oc:active", - "oc:amountInk", - "oc:amountMaterial", - "oc:limit", - "oc:remaining", - "oc:total" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/raid.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/raid.json deleted file mode 100644 index 7a52c2ef3b..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/raid.json +++ /dev/null @@ -1,7 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/inventory.json", - "traits/rotatable.json" - ] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/redstone.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/redstone.json deleted file mode 100644 index f2be27863f..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/redstone.json +++ /dev/null @@ -1,8 +0,0 @@ -[{ - "includes": ["traits/redstone.json"], - "nbt": { - "blacklist": [ - "oc:redstone/node" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/relay.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/relay.json deleted file mode 100644 index 8853509610..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/relay.json +++ /dev/null @@ -1,12 +0,0 @@ -[{ - "includes": [ - "traits/hub.json", - "traits/inventory.json", - "traits/powerAcceptor.json" - ], - "nbt": { - "blacklist": [ - "oc:componentNodes" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/robot.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/robot.json deleted file mode 100644 index 53641eb9c1..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/robot.json +++ /dev/null @@ -1,24 +0,0 @@ -[{ - "includes": [ - "traits/computer.json", - "traits/environment.json", - "traits/inventory.json", - "traits/redstone.json", - "traits/rotatable.json" - ], - "nbt": { - "blacklist": [ - "display", - "oc:components", - "oc:containers", - "oc:lightColor", - "oc:owner", - "oc:ownerUuid", - "oc:robot", - "oc:robotEnergy", - "oc:selectedSlot", - "oc:selectedTank", - "oc:storedEnergy" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen.json deleted file mode 100644 index 369d342734..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen.json +++ /dev/null @@ -1,14 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/externalData.json", - "traits/redstone.json", - "traits/rotatable.json" - ], - "nbt": { - "blacklist": [ - "oc:hasPower", - "oc:hadRedstoneInput" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen1.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen1.json deleted file mode 100644 index dadd2bf74b..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen1.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["screen.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen2.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen2.json deleted file mode 100644 index dadd2bf74b..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen2.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["screen.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen3.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen3.json deleted file mode 100644 index dadd2bf74b..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/screen3.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["screen.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/serverRack.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/serverRack.json deleted file mode 100644 index 06dc5c6697..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/serverRack.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "includes": [ - "traits/hub.json", - "traits/inventory.json", - "traits/powerAcceptor.json", - "traits/redstone.json", - "traits/rotatable.json" - ], - "nbt": { - "blacklist": [ - "oc:servers", - "oc:terminals" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/computer.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/computer.json deleted file mode 100644 index d90950be10..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/computer.json +++ /dev/null @@ -1,7 +0,0 @@ -[{ - "nbt": { - "blacklist": [ - "oc:computer" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/environment.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/environment.json deleted file mode 100644 index b91cf6986e..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/environment.json +++ /dev/null @@ -1,8 +0,0 @@ -[{ - "nbt": { - "blacklist": [ - "node", - "oc:node" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/externalData.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/externalData.json deleted file mode 100644 index c579dec594..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/externalData.json +++ /dev/null @@ -1,9 +0,0 @@ -[{ - "nbt": { - "blacklist": [ - "chunkX", - "chunkZ", - "dimension" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/hub.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/hub.json deleted file mode 100644 index 6994b8091a..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/hub.json +++ /dev/null @@ -1,8 +0,0 @@ -[{ - "nbt": { - "blacklist": [ - "oc:plugs", - "oc:queue" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/inventory.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/inventory.json deleted file mode 100644 index f16d956de6..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/inventory.json +++ /dev/null @@ -1,8 +0,0 @@ -[{ - "ignoreInventoryContents": true, - "nbt": { - "blacklist": [ - "oc:items" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/powerAcceptor.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/powerAcceptor.json deleted file mode 100644 index 7500c660bc..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/powerAcceptor.json +++ /dev/null @@ -1,9 +0,0 @@ -[{ - "nbt": { - "blacklist": [ - "oc:ae2power", - "oc:ic2power", - "oc:ic2cpower" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/redstone.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/redstone.json deleted file mode 100644 index 6b28180698..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/redstone.json +++ /dev/null @@ -1,11 +0,0 @@ -[{ - "nbt": { - "blacklist": [ - "oc:rs.input", - "oc:rs.output", - "oc:rs.bundledInput", - "oc:rs.bundledOutput", - "oc:rs.rednetInput" - ] - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/rotatable.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/rotatable.json deleted file mode 100644 index 2168077cf8..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/traits/rotatable.json +++ /dev/null @@ -1,7 +0,0 @@ -[{ - "rotation": { - "type": "nbtField", - "tag": "oc:yaw", - "format": "ForgeDirection" - } -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/transposer.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/transposer.json deleted file mode 100644 index 2a5da92da9..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/transposer.json +++ /dev/null @@ -1,3 +0,0 @@ -[{ - "includes": ["traits/environment.json"] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/bcbuilder/blocks/waypoint.json b/src/main/resources/assets/opencomputers/bcbuilder/blocks/waypoint.json deleted file mode 100644 index 556f25dc77..0000000000 --- a/src/main/resources/assets/opencomputers/bcbuilder/blocks/waypoint.json +++ /dev/null @@ -1,7 +0,0 @@ -[{ - "includes": [ - "traits/environment.json", - "traits/redstone.json", - "traits/rotatable.json" - ] -}] \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/blockstates/accesspoint.json b/src/main/resources/assets/opencomputers/blockstates/accesspoint.json index 617e1a249b..90e6d47100 100644 --- a/src/main/resources/assets/opencomputers/blockstates/accesspoint.json +++ b/src/main/resources/assets/opencomputers/blockstates/accesspoint.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:accesspoint" } + "": { "model": "opencomputers:block/accesspoint" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/adapter.json b/src/main/resources/assets/opencomputers/blockstates/adapter.json index 55444855fe..1893a7394b 100644 --- a/src/main/resources/assets/opencomputers/blockstates/adapter.json +++ b/src/main/resources/assets/opencomputers/blockstates/adapter.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:adapter" } + "": { "model": "opencomputers:block/adapter" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/assembler.json b/src/main/resources/assets/opencomputers/blockstates/assembler.json index b89ed2b1fd..f9cf866fce 100644 --- a/src/main/resources/assets/opencomputers/blockstates/assembler.json +++ b/src/main/resources/assets/opencomputers/blockstates/assembler.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:assembler" } + "": { "model": "opencomputers:block/assembler" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/cable.json b/src/main/resources/assets/opencomputers/blockstates/cable.json new file mode 100644 index 0000000000..dbeef9edc2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/blockstates/cable.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "minecraft:block/air" } + } +} diff --git a/src/main/resources/assets/opencomputers/blockstates/capacitor.json b/src/main/resources/assets/opencomputers/blockstates/capacitor.json index 7887a194f2..ab9a30aebd 100644 --- a/src/main/resources/assets/opencomputers/blockstates/capacitor.json +++ b/src/main/resources/assets/opencomputers/blockstates/capacitor.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:capacitor" } + "": { "model": "opencomputers:block/capacitor" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/carpetedcapacitor.json b/src/main/resources/assets/opencomputers/blockstates/carpetedcapacitor.json index f6c92cb33b..43bb89c09f 100644 --- a/src/main/resources/assets/opencomputers/blockstates/carpetedcapacitor.json +++ b/src/main/resources/assets/opencomputers/blockstates/carpetedcapacitor.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:carpetedcapacitor" } + "": { "model": "opencomputers:block/carpetedcapacitor" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/case1.json b/src/main/resources/assets/opencomputers/blockstates/case1.json index 2ed08635bd..22429bafcf 100644 --- a/src/main/resources/assets/opencomputers/blockstates/case1.json +++ b/src/main/resources/assets/opencomputers/blockstates/case1.json @@ -1,12 +1,12 @@ { "variants": { - "facing=north,running=false": { "model": "opencomputers:case" }, - "facing=south,running=false": { "model": "opencomputers:case", "y": 180 }, - "facing=west,running=false": { "model": "opencomputers:case", "y": 270 }, - "facing=east,running=false": { "model": "opencomputers:case", "y": 90 }, - "facing=north,running=true": { "model": "opencomputers:case_running" }, - "facing=south,running=true": { "model": "opencomputers:case_running", "y": 180 }, - "facing=west,running=true": { "model": "opencomputers:case_running", "y": 270 }, - "facing=east,running=true": { "model": "opencomputers:case_running", "y": 90 } + "facing=north,running=false": { "model": "opencomputers:block/case" }, + "facing=south,running=false": { "model": "opencomputers:block/case", "y": 180 }, + "facing=west,running=false": { "model": "opencomputers:block/case", "y": 270 }, + "facing=east,running=false": { "model": "opencomputers:block/case", "y": 90 }, + "facing=north,running=true": { "model": "opencomputers:block/case_running" }, + "facing=south,running=true": { "model": "opencomputers:block/case_running", "y": 180 }, + "facing=west,running=true": { "model": "opencomputers:block/case_running", "y": 270 }, + "facing=east,running=true": { "model": "opencomputers:block/case_running", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/case2.json b/src/main/resources/assets/opencomputers/blockstates/case2.json index 2ed08635bd..22429bafcf 100644 --- a/src/main/resources/assets/opencomputers/blockstates/case2.json +++ b/src/main/resources/assets/opencomputers/blockstates/case2.json @@ -1,12 +1,12 @@ { "variants": { - "facing=north,running=false": { "model": "opencomputers:case" }, - "facing=south,running=false": { "model": "opencomputers:case", "y": 180 }, - "facing=west,running=false": { "model": "opencomputers:case", "y": 270 }, - "facing=east,running=false": { "model": "opencomputers:case", "y": 90 }, - "facing=north,running=true": { "model": "opencomputers:case_running" }, - "facing=south,running=true": { "model": "opencomputers:case_running", "y": 180 }, - "facing=west,running=true": { "model": "opencomputers:case_running", "y": 270 }, - "facing=east,running=true": { "model": "opencomputers:case_running", "y": 90 } + "facing=north,running=false": { "model": "opencomputers:block/case" }, + "facing=south,running=false": { "model": "opencomputers:block/case", "y": 180 }, + "facing=west,running=false": { "model": "opencomputers:block/case", "y": 270 }, + "facing=east,running=false": { "model": "opencomputers:block/case", "y": 90 }, + "facing=north,running=true": { "model": "opencomputers:block/case_running" }, + "facing=south,running=true": { "model": "opencomputers:block/case_running", "y": 180 }, + "facing=west,running=true": { "model": "opencomputers:block/case_running", "y": 270 }, + "facing=east,running=true": { "model": "opencomputers:block/case_running", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/case3.json b/src/main/resources/assets/opencomputers/blockstates/case3.json index 2ed08635bd..22429bafcf 100644 --- a/src/main/resources/assets/opencomputers/blockstates/case3.json +++ b/src/main/resources/assets/opencomputers/blockstates/case3.json @@ -1,12 +1,12 @@ { "variants": { - "facing=north,running=false": { "model": "opencomputers:case" }, - "facing=south,running=false": { "model": "opencomputers:case", "y": 180 }, - "facing=west,running=false": { "model": "opencomputers:case", "y": 270 }, - "facing=east,running=false": { "model": "opencomputers:case", "y": 90 }, - "facing=north,running=true": { "model": "opencomputers:case_running" }, - "facing=south,running=true": { "model": "opencomputers:case_running", "y": 180 }, - "facing=west,running=true": { "model": "opencomputers:case_running", "y": 270 }, - "facing=east,running=true": { "model": "opencomputers:case_running", "y": 90 } + "facing=north,running=false": { "model": "opencomputers:block/case" }, + "facing=south,running=false": { "model": "opencomputers:block/case", "y": 180 }, + "facing=west,running=false": { "model": "opencomputers:block/case", "y": 270 }, + "facing=east,running=false": { "model": "opencomputers:block/case", "y": 90 }, + "facing=north,running=true": { "model": "opencomputers:block/case_running" }, + "facing=south,running=true": { "model": "opencomputers:block/case_running", "y": 180 }, + "facing=west,running=true": { "model": "opencomputers:block/case_running", "y": 270 }, + "facing=east,running=true": { "model": "opencomputers:block/case_running", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/casecreative.json b/src/main/resources/assets/opencomputers/blockstates/casecreative.json index 2ed08635bd..22429bafcf 100644 --- a/src/main/resources/assets/opencomputers/blockstates/casecreative.json +++ b/src/main/resources/assets/opencomputers/blockstates/casecreative.json @@ -1,12 +1,12 @@ { "variants": { - "facing=north,running=false": { "model": "opencomputers:case" }, - "facing=south,running=false": { "model": "opencomputers:case", "y": 180 }, - "facing=west,running=false": { "model": "opencomputers:case", "y": 270 }, - "facing=east,running=false": { "model": "opencomputers:case", "y": 90 }, - "facing=north,running=true": { "model": "opencomputers:case_running" }, - "facing=south,running=true": { "model": "opencomputers:case_running", "y": 180 }, - "facing=west,running=true": { "model": "opencomputers:case_running", "y": 270 }, - "facing=east,running=true": { "model": "opencomputers:case_running", "y": 90 } + "facing=north,running=false": { "model": "opencomputers:block/case" }, + "facing=south,running=false": { "model": "opencomputers:block/case", "y": 180 }, + "facing=west,running=false": { "model": "opencomputers:block/case", "y": 270 }, + "facing=east,running=false": { "model": "opencomputers:block/case", "y": 90 }, + "facing=north,running=true": { "model": "opencomputers:block/case_running" }, + "facing=south,running=true": { "model": "opencomputers:block/case_running", "y": 180 }, + "facing=west,running=true": { "model": "opencomputers:block/case_running", "y": 270 }, + "facing=east,running=true": { "model": "opencomputers:block/case_running", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/chameliumblock.json b/src/main/resources/assets/opencomputers/blockstates/chameliumblock.json index b1affded73..4f4f19a937 100644 --- a/src/main/resources/assets/opencomputers/blockstates/chameliumblock.json +++ b/src/main/resources/assets/opencomputers/blockstates/chameliumblock.json @@ -1,20 +1,20 @@ { "variants": { - "color=silver": { "model": "opencomputers:chameliumblock" }, - "color=magenta": { "model": "opencomputers:chameliumblock" }, - "color=light_blue": { "model": "opencomputers:chameliumblock" }, - "color=red": { "model": "opencomputers:chameliumblock" }, - "color=yellow": { "model": "opencomputers:chameliumblock" }, - "color=gray": { "model": "opencomputers:chameliumblock" }, - "color=brown": { "model": "opencomputers:chameliumblock" }, - "color=cyan": { "model": "opencomputers:chameliumblock" }, - "color=green": { "model": "opencomputers:chameliumblock" }, - "color=blue": { "model": "opencomputers:chameliumblock" }, - "color=purple": { "model": "opencomputers:chameliumblock" }, - "color=orange": { "model": "opencomputers:chameliumblock" }, - "color=pink": { "model": "opencomputers:chameliumblock" }, - "color=black": { "model": "opencomputers:chameliumblock" }, - "color=white": { "model": "opencomputers:chameliumblock" }, - "color=lime": { "model": "opencomputers:chameliumblock" } + "color=light_gray": { "model": "opencomputers:block/chameliumblock" }, + "color=magenta": { "model": "opencomputers:block/chameliumblock" }, + "color=light_blue": { "model": "opencomputers:block/chameliumblock" }, + "color=red": { "model": "opencomputers:block/chameliumblock" }, + "color=yellow": { "model": "opencomputers:block/chameliumblock" }, + "color=gray": { "model": "opencomputers:block/chameliumblock" }, + "color=brown": { "model": "opencomputers:block/chameliumblock" }, + "color=cyan": { "model": "opencomputers:block/chameliumblock" }, + "color=green": { "model": "opencomputers:block/chameliumblock" }, + "color=blue": { "model": "opencomputers:block/chameliumblock" }, + "color=purple": { "model": "opencomputers:block/chameliumblock" }, + "color=orange": { "model": "opencomputers:block/chameliumblock" }, + "color=pink": { "model": "opencomputers:block/chameliumblock" }, + "color=black": { "model": "opencomputers:block/chameliumblock" }, + "color=white": { "model": "opencomputers:block/chameliumblock" }, + "color=lime": { "model": "opencomputers:block/chameliumblock" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/charger.json b/src/main/resources/assets/opencomputers/blockstates/charger.json index 54cebc64e8..6d0afd9e90 100644 --- a/src/main/resources/assets/opencomputers/blockstates/charger.json +++ b/src/main/resources/assets/opencomputers/blockstates/charger.json @@ -1,8 +1,8 @@ { "variants": { - "facing=north": { "model": "opencomputers:charger" }, - "facing=south": { "model": "opencomputers:charger", "y": 180 }, - "facing=west": { "model": "opencomputers:charger", "y": 270 }, - "facing=east": { "model": "opencomputers:charger", "y": 90 } + "facing=north": { "model": "opencomputers:block/charger" }, + "facing=south": { "model": "opencomputers:block/charger", "y": 180 }, + "facing=west": { "model": "opencomputers:block/charger", "y": 270 }, + "facing=east": { "model": "opencomputers:block/charger", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/disassembler.json b/src/main/resources/assets/opencomputers/blockstates/disassembler.json index 8b7823ccfa..2ce043f06c 100644 --- a/src/main/resources/assets/opencomputers/blockstates/disassembler.json +++ b/src/main/resources/assets/opencomputers/blockstates/disassembler.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:disassembler" } + "": { "model": "opencomputers:block/disassembler" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/diskdrive.json b/src/main/resources/assets/opencomputers/blockstates/diskdrive.json index c157589956..68bc7d87df 100644 --- a/src/main/resources/assets/opencomputers/blockstates/diskdrive.json +++ b/src/main/resources/assets/opencomputers/blockstates/diskdrive.json @@ -1,8 +1,8 @@ { "variants": { - "facing=north": { "model": "opencomputers:diskdrive" }, - "facing=south": { "model": "opencomputers:diskdrive", "y": 180 }, - "facing=west": { "model": "opencomputers:diskdrive", "y": 270 }, - "facing=east": { "model": "opencomputers:diskdrive", "y": 90 } + "facing=north": { "model": "opencomputers:block/diskdrive" }, + "facing=south": { "model": "opencomputers:block/diskdrive", "y": 180 }, + "facing=west": { "model": "opencomputers:block/diskdrive", "y": 270 }, + "facing=east": { "model": "opencomputers:block/diskdrive", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/endstone.json b/src/main/resources/assets/opencomputers/blockstates/endstone.json index 128583c89f..f14a18da61 100644 --- a/src/main/resources/assets/opencomputers/blockstates/endstone.json +++ b/src/main/resources/assets/opencomputers/blockstates/endstone.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "minecraft:end_stone" } + "": { "model": "minecraft:block/end_stone" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/geolyzer.json b/src/main/resources/assets/opencomputers/blockstates/geolyzer.json index 006954e9d3..7ee1d77440 100644 --- a/src/main/resources/assets/opencomputers/blockstates/geolyzer.json +++ b/src/main/resources/assets/opencomputers/blockstates/geolyzer.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:geolyzer" } + "": { "model": "opencomputers:block/geolyzer" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/hologram1.json b/src/main/resources/assets/opencomputers/blockstates/hologram1.json index e35d1d4984..0d567612b4 100644 --- a/src/main/resources/assets/opencomputers/blockstates/hologram1.json +++ b/src/main/resources/assets/opencomputers/blockstates/hologram1.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:hologram1" } + "": { "model": "opencomputers:block/hologram1" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/hologram2.json b/src/main/resources/assets/opencomputers/blockstates/hologram2.json index f0f48e0c77..21638bd491 100644 --- a/src/main/resources/assets/opencomputers/blockstates/hologram2.json +++ b/src/main/resources/assets/opencomputers/blockstates/hologram2.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:hologram2" } + "": { "model": "opencomputers:block/hologram2" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/keyboard.json b/src/main/resources/assets/opencomputers/blockstates/keyboard.json index 242fa77a4b..1490131bb4 100644 --- a/src/main/resources/assets/opencomputers/blockstates/keyboard.json +++ b/src/main/resources/assets/opencomputers/blockstates/keyboard.json @@ -1,16 +1,16 @@ { "variants": { - "pitch=north,yaw=north": { "model": "opencomputers:keyboard" }, - "pitch=north,yaw=east": { "model": "opencomputers:keyboard", "y": 90 }, - "pitch=north,yaw=south": { "model": "opencomputers:keyboard", "y": 180 }, - "pitch=north,yaw=west": { "model": "opencomputers:keyboard", "y": 270 }, - "pitch=up,yaw=north": { "model": "opencomputers:keyboard", "x": -90, "y": 180 }, - "pitch=up,yaw=east": { "model": "opencomputers:keyboard", "x": -90, "y": 270 }, - "pitch=up,yaw=south": { "model": "opencomputers:keyboard", "x": -90 }, - "pitch=up,yaw=west": { "model": "opencomputers:keyboard", "x": -90, "y": 90 }, - "pitch=down,yaw=north": { "model": "opencomputers:keyboard", "x": 90, "y": 180 }, - "pitch=down,yaw=east": { "model": "opencomputers:keyboard", "x": 90, "y": 270 }, - "pitch=down,yaw=south": { "model": "opencomputers:keyboard", "x": 90 }, - "pitch=down,yaw=west": { "model": "opencomputers:keyboard", "x": 90, "y": 90 } + "pitch=north,yaw=north": { "model": "opencomputers:block/keyboard" }, + "pitch=north,yaw=east": { "model": "opencomputers:block/keyboard", "y": 90 }, + "pitch=north,yaw=south": { "model": "opencomputers:block/keyboard", "y": 180 }, + "pitch=north,yaw=west": { "model": "opencomputers:block/keyboard", "y": 270 }, + "pitch=up,yaw=north": { "model": "opencomputers:block/keyboard", "x": -90, "y": 180 }, + "pitch=up,yaw=east": { "model": "opencomputers:block/keyboard", "x": -90, "y": 270 }, + "pitch=up,yaw=south": { "model": "opencomputers:block/keyboard", "x": -90 }, + "pitch=up,yaw=west": { "model": "opencomputers:block/keyboard", "x": -90, "y": 90 }, + "pitch=down,yaw=north": { "model": "opencomputers:block/keyboard", "x": 90, "y": 180 }, + "pitch=down,yaw=east": { "model": "opencomputers:block/keyboard", "x": 90, "y": 270 }, + "pitch=down,yaw=south": { "model": "opencomputers:block/keyboard", "x": 90 }, + "pitch=down,yaw=west": { "model": "opencomputers:block/keyboard", "x": 90, "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/microcontroller.json b/src/main/resources/assets/opencomputers/blockstates/microcontroller.json index ae4a9aa8ea..c329e47fa9 100644 --- a/src/main/resources/assets/opencomputers/blockstates/microcontroller.json +++ b/src/main/resources/assets/opencomputers/blockstates/microcontroller.json @@ -1,8 +1,8 @@ { "variants": { - "facing=north": { "model": "opencomputers:microcontroller" }, - "facing=south": { "model": "opencomputers:microcontroller", "y": 180 }, - "facing=west": { "model": "opencomputers:microcontroller", "y": 270 }, - "facing=east": { "model": "opencomputers:microcontroller", "y": 90 } + "facing=north": { "model": "opencomputers:block/microcontroller" }, + "facing=south": { "model": "opencomputers:block/microcontroller", "y": 180 }, + "facing=west": { "model": "opencomputers:block/microcontroller", "y": 270 }, + "facing=east": { "model": "opencomputers:block/microcontroller", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/motionsensor.json b/src/main/resources/assets/opencomputers/blockstates/motionsensor.json index 6be6d0c07a..f1181d7ab7 100644 --- a/src/main/resources/assets/opencomputers/blockstates/motionsensor.json +++ b/src/main/resources/assets/opencomputers/blockstates/motionsensor.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:motionsensor" } + "": { "model": "opencomputers:block/motionsensor" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/netsplitter.json b/src/main/resources/assets/opencomputers/blockstates/netsplitter.json new file mode 100644 index 0000000000..dbeef9edc2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/blockstates/netsplitter.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "minecraft:block/air" } + } +} diff --git a/src/main/resources/assets/opencomputers/blockstates/powerconverter.json b/src/main/resources/assets/opencomputers/blockstates/powerconverter.json index 3fc72045cf..47e646e637 100644 --- a/src/main/resources/assets/opencomputers/blockstates/powerconverter.json +++ b/src/main/resources/assets/opencomputers/blockstates/powerconverter.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:powerconverter" } + "": { "model": "opencomputers:block/powerconverter" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/powerdistributor.json b/src/main/resources/assets/opencomputers/blockstates/powerdistributor.json index 3ab0491654..2194435bd2 100644 --- a/src/main/resources/assets/opencomputers/blockstates/powerdistributor.json +++ b/src/main/resources/assets/opencomputers/blockstates/powerdistributor.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:powerdistributor" } + "": { "model": "opencomputers:block/powerdistributor" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/print.json b/src/main/resources/assets/opencomputers/blockstates/print.json new file mode 100644 index 0000000000..dbeef9edc2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/blockstates/print.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "minecraft:block/air" } + } +} diff --git a/src/main/resources/assets/opencomputers/blockstates/printer.json b/src/main/resources/assets/opencomputers/blockstates/printer.json index 18e8d7c5b4..e87119e7bd 100644 --- a/src/main/resources/assets/opencomputers/blockstates/printer.json +++ b/src/main/resources/assets/opencomputers/blockstates/printer.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:printer" } + "": { "model": "opencomputers:block/printer" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/rack.json b/src/main/resources/assets/opencomputers/blockstates/rack.json index 98bad44b77..27c0034d94 100644 --- a/src/main/resources/assets/opencomputers/blockstates/rack.json +++ b/src/main/resources/assets/opencomputers/blockstates/rack.json @@ -1,8 +1,8 @@ { "variants": { - "facing=north": { "model": "opencomputers:rack" }, - "facing=south": { "model": "opencomputers:rack", "y": 180 }, - "facing=west": { "model": "opencomputers:rack", "y": 270 }, - "facing=east": { "model": "opencomputers:rack", "y": 90 } + "facing=north": { "model": "opencomputers:block/rack" }, + "facing=south": { "model": "opencomputers:block/rack", "y": 180 }, + "facing=west": { "model": "opencomputers:block/rack", "y": 270 }, + "facing=east": { "model": "opencomputers:block/rack", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/raid.json b/src/main/resources/assets/opencomputers/blockstates/raid.json index 84de291f81..d9c02591a8 100644 --- a/src/main/resources/assets/opencomputers/blockstates/raid.json +++ b/src/main/resources/assets/opencomputers/blockstates/raid.json @@ -1,8 +1,8 @@ { "variants": { - "facing=north": { "model": "opencomputers:raid" }, - "facing=south": { "model": "opencomputers:raid", "y": 180 }, - "facing=west": { "model": "opencomputers:raid", "y": 270 }, - "facing=east": { "model": "opencomputers:raid", "y": 90 } + "facing=north": { "model": "opencomputers:block/raid" }, + "facing=south": { "model": "opencomputers:block/raid", "y": 180 }, + "facing=west": { "model": "opencomputers:block/raid", "y": 270 }, + "facing=east": { "model": "opencomputers:block/raid", "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/redstone.json b/src/main/resources/assets/opencomputers/blockstates/redstone.json index bd41205b87..db1ee2bed2 100644 --- a/src/main/resources/assets/opencomputers/blockstates/redstone.json +++ b/src/main/resources/assets/opencomputers/blockstates/redstone.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:redstone" } + "": { "model": "opencomputers:block/redstone" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/relay.json b/src/main/resources/assets/opencomputers/blockstates/relay.json index bb04449098..2ec907449b 100644 --- a/src/main/resources/assets/opencomputers/blockstates/relay.json +++ b/src/main/resources/assets/opencomputers/blockstates/relay.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:relay" } + "": { "model": "opencomputers:block/relay" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/robot.json b/src/main/resources/assets/opencomputers/blockstates/robot.json new file mode 100644 index 0000000000..dbeef9edc2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/blockstates/robot.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "minecraft:block/air" } + } +} diff --git a/src/main/resources/assets/opencomputers/blockstates/robotafterimage.json b/src/main/resources/assets/opencomputers/blockstates/robotafterimage.json new file mode 100644 index 0000000000..dbeef9edc2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/blockstates/robotafterimage.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "minecraft:block/air" } + } +} diff --git a/src/main/resources/assets/opencomputers/blockstates/screen1.json b/src/main/resources/assets/opencomputers/blockstates/screen1.json index b54966d253..63967b93f2 100644 --- a/src/main/resources/assets/opencomputers/blockstates/screen1.json +++ b/src/main/resources/assets/opencomputers/blockstates/screen1.json @@ -1,16 +1,16 @@ { "variants": { - "pitch=north,yaw=north": { "model": "opencomputers:screen" }, - "pitch=north,yaw=south": { "model": "opencomputers:screen", "y": 180 }, - "pitch=north,yaw=east": { "model": "opencomputers:screen", "y": 270 }, - "pitch=north,yaw=west": { "model": "opencomputers:screen", "y": 90 }, - "pitch=up,yaw=north": { "model": "opencomputers:screen", "x": 90 }, - "pitch=up,yaw=south": { "model": "opencomputers:screen", "x": 90, "y": 180 }, - "pitch=up,yaw=east": { "model": "opencomputers:screen", "x": 90, "y": 270 }, - "pitch=up,yaw=west": { "model": "opencomputers:screen", "x": 90, "y": 90 }, - "pitch=down,yaw=north": { "model": "opencomputers:screen", "x": -90 }, - "pitch=down,yaw=south": { "model": "opencomputers:screen", "x": -90, "y": 180 }, - "pitch=down,yaw=east": { "model": "opencomputers:screen", "x": -90, "y": 270 }, - "pitch=down,yaw=west": { "model": "opencomputers:screen", "x": -90, "y": 90 } + "pitch=north,yaw=north": { "model": "opencomputers:block/screen" }, + "pitch=north,yaw=south": { "model": "opencomputers:block/screen", "y": 180 }, + "pitch=north,yaw=east": { "model": "opencomputers:block/screen", "y": 270 }, + "pitch=north,yaw=west": { "model": "opencomputers:block/screen", "y": 90 }, + "pitch=up,yaw=north": { "model": "opencomputers:block/screen", "x": 90 }, + "pitch=up,yaw=south": { "model": "opencomputers:block/screen", "x": 90, "y": 180 }, + "pitch=up,yaw=east": { "model": "opencomputers:block/screen", "x": 90, "y": 270 }, + "pitch=up,yaw=west": { "model": "opencomputers:block/screen", "x": 90, "y": 90 }, + "pitch=down,yaw=north": { "model": "opencomputers:block/screen", "x": -90 }, + "pitch=down,yaw=south": { "model": "opencomputers:block/screen", "x": -90, "y": 180 }, + "pitch=down,yaw=east": { "model": "opencomputers:block/screen", "x": -90, "y": 270 }, + "pitch=down,yaw=west": { "model": "opencomputers:block/screen", "x": -90, "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/screen2.json b/src/main/resources/assets/opencomputers/blockstates/screen2.json index b54966d253..63967b93f2 100644 --- a/src/main/resources/assets/opencomputers/blockstates/screen2.json +++ b/src/main/resources/assets/opencomputers/blockstates/screen2.json @@ -1,16 +1,16 @@ { "variants": { - "pitch=north,yaw=north": { "model": "opencomputers:screen" }, - "pitch=north,yaw=south": { "model": "opencomputers:screen", "y": 180 }, - "pitch=north,yaw=east": { "model": "opencomputers:screen", "y": 270 }, - "pitch=north,yaw=west": { "model": "opencomputers:screen", "y": 90 }, - "pitch=up,yaw=north": { "model": "opencomputers:screen", "x": 90 }, - "pitch=up,yaw=south": { "model": "opencomputers:screen", "x": 90, "y": 180 }, - "pitch=up,yaw=east": { "model": "opencomputers:screen", "x": 90, "y": 270 }, - "pitch=up,yaw=west": { "model": "opencomputers:screen", "x": 90, "y": 90 }, - "pitch=down,yaw=north": { "model": "opencomputers:screen", "x": -90 }, - "pitch=down,yaw=south": { "model": "opencomputers:screen", "x": -90, "y": 180 }, - "pitch=down,yaw=east": { "model": "opencomputers:screen", "x": -90, "y": 270 }, - "pitch=down,yaw=west": { "model": "opencomputers:screen", "x": -90, "y": 90 } + "pitch=north,yaw=north": { "model": "opencomputers:block/screen" }, + "pitch=north,yaw=south": { "model": "opencomputers:block/screen", "y": 180 }, + "pitch=north,yaw=east": { "model": "opencomputers:block/screen", "y": 270 }, + "pitch=north,yaw=west": { "model": "opencomputers:block/screen", "y": 90 }, + "pitch=up,yaw=north": { "model": "opencomputers:block/screen", "x": 90 }, + "pitch=up,yaw=south": { "model": "opencomputers:block/screen", "x": 90, "y": 180 }, + "pitch=up,yaw=east": { "model": "opencomputers:block/screen", "x": 90, "y": 270 }, + "pitch=up,yaw=west": { "model": "opencomputers:block/screen", "x": 90, "y": 90 }, + "pitch=down,yaw=north": { "model": "opencomputers:block/screen", "x": -90 }, + "pitch=down,yaw=south": { "model": "opencomputers:block/screen", "x": -90, "y": 180 }, + "pitch=down,yaw=east": { "model": "opencomputers:block/screen", "x": -90, "y": 270 }, + "pitch=down,yaw=west": { "model": "opencomputers:block/screen", "x": -90, "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/screen3.json b/src/main/resources/assets/opencomputers/blockstates/screen3.json index b54966d253..63967b93f2 100644 --- a/src/main/resources/assets/opencomputers/blockstates/screen3.json +++ b/src/main/resources/assets/opencomputers/blockstates/screen3.json @@ -1,16 +1,16 @@ { "variants": { - "pitch=north,yaw=north": { "model": "opencomputers:screen" }, - "pitch=north,yaw=south": { "model": "opencomputers:screen", "y": 180 }, - "pitch=north,yaw=east": { "model": "opencomputers:screen", "y": 270 }, - "pitch=north,yaw=west": { "model": "opencomputers:screen", "y": 90 }, - "pitch=up,yaw=north": { "model": "opencomputers:screen", "x": 90 }, - "pitch=up,yaw=south": { "model": "opencomputers:screen", "x": 90, "y": 180 }, - "pitch=up,yaw=east": { "model": "opencomputers:screen", "x": 90, "y": 270 }, - "pitch=up,yaw=west": { "model": "opencomputers:screen", "x": 90, "y": 90 }, - "pitch=down,yaw=north": { "model": "opencomputers:screen", "x": -90 }, - "pitch=down,yaw=south": { "model": "opencomputers:screen", "x": -90, "y": 180 }, - "pitch=down,yaw=east": { "model": "opencomputers:screen", "x": -90, "y": 270 }, - "pitch=down,yaw=west": { "model": "opencomputers:screen", "x": -90, "y": 90 } + "pitch=north,yaw=north": { "model": "opencomputers:block/screen" }, + "pitch=north,yaw=south": { "model": "opencomputers:block/screen", "y": 180 }, + "pitch=north,yaw=east": { "model": "opencomputers:block/screen", "y": 270 }, + "pitch=north,yaw=west": { "model": "opencomputers:block/screen", "y": 90 }, + "pitch=up,yaw=north": { "model": "opencomputers:block/screen", "x": 90 }, + "pitch=up,yaw=south": { "model": "opencomputers:block/screen", "x": 90, "y": 180 }, + "pitch=up,yaw=east": { "model": "opencomputers:block/screen", "x": 90, "y": 270 }, + "pitch=up,yaw=west": { "model": "opencomputers:block/screen", "x": 90, "y": 90 }, + "pitch=down,yaw=north": { "model": "opencomputers:block/screen", "x": -90 }, + "pitch=down,yaw=south": { "model": "opencomputers:block/screen", "x": -90, "y": 180 }, + "pitch=down,yaw=east": { "model": "opencomputers:block/screen", "x": -90, "y": 270 }, + "pitch=down,yaw=west": { "model": "opencomputers:block/screen", "x": -90, "y": 90 } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/switch.json b/src/main/resources/assets/opencomputers/blockstates/switch.json index 18c289b041..24f1db9d96 100644 --- a/src/main/resources/assets/opencomputers/blockstates/switch.json +++ b/src/main/resources/assets/opencomputers/blockstates/switch.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:switch" } + "": { "model": "opencomputers:block/switch" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/transposer.json b/src/main/resources/assets/opencomputers/blockstates/transposer.json index 32bd3dad6d..eb059ab372 100644 --- a/src/main/resources/assets/opencomputers/blockstates/transposer.json +++ b/src/main/resources/assets/opencomputers/blockstates/transposer.json @@ -1,5 +1,5 @@ { "variants": { - "normal": { "model": "opencomputers:transposer" } + "": { "model": "opencomputers:block/transposer" } } } diff --git a/src/main/resources/assets/opencomputers/blockstates/waypoint.json b/src/main/resources/assets/opencomputers/blockstates/waypoint.json index 2b4a7f93db..1c856cd5ad 100644 --- a/src/main/resources/assets/opencomputers/blockstates/waypoint.json +++ b/src/main/resources/assets/opencomputers/blockstates/waypoint.json @@ -1,16 +1,16 @@ { "variants": { - "pitch=north,yaw=north": { "model": "opencomputers:waypoint" }, - "pitch=north,yaw=east": { "model": "opencomputers:waypoint", "y": 90 }, - "pitch=north,yaw=south": { "model": "opencomputers:waypoint", "y": 180 }, - "pitch=north,yaw=west": { "model": "opencomputers:waypoint", "y": 270 }, - "pitch=up,yaw=north": { "model": "opencomputers:waypoint", "x": -90 }, - "pitch=up,yaw=east": { "model": "opencomputers:waypoint", "x": -90, "y": 90 }, - "pitch=up,yaw=south": { "model": "opencomputers:waypoint", "x": -90, "y": 180 }, - "pitch=up,yaw=west": { "model": "opencomputers:waypoint", "x": -90, "y": 270 }, - "pitch=down,yaw=north": { "model": "opencomputers:waypoint", "x": 90 }, - "pitch=down,yaw=east": { "model": "opencomputers:waypoint", "x": 90, "y": 90 }, - "pitch=down,yaw=south": { "model": "opencomputers:waypoint", "x": 90, "y": 180 }, - "pitch=down,yaw=west": { "model": "opencomputers:waypoint", "x": 90, "y": 270 } + "pitch=north,yaw=north": { "model": "opencomputers:block/waypoint" }, + "pitch=north,yaw=east": { "model": "opencomputers:block/waypoint", "y": 90 }, + "pitch=north,yaw=south": { "model": "opencomputers:block/waypoint", "y": 180 }, + "pitch=north,yaw=west": { "model": "opencomputers:block/waypoint", "y": 270 }, + "pitch=up,yaw=north": { "model": "opencomputers:block/waypoint", "x": -90 }, + "pitch=up,yaw=east": { "model": "opencomputers:block/waypoint", "x": -90, "y": 90 }, + "pitch=up,yaw=south": { "model": "opencomputers:block/waypoint", "x": -90, "y": 180 }, + "pitch=up,yaw=west": { "model": "opencomputers:block/waypoint", "x": -90, "y": 270 }, + "pitch=down,yaw=north": { "model": "opencomputers:block/waypoint", "x": 90 }, + "pitch=down,yaw=east": { "model": "opencomputers:block/waypoint", "x": 90, "y": 90 }, + "pitch=down,yaw=south": { "model": "opencomputers:block/waypoint", "x": 90, "y": 180 }, + "pitch=down,yaw=west": { "model": "opencomputers:block/waypoint", "x": 90, "y": 270 } } } diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/adapter.md b/src/main/resources/assets/opencomputers/doc/de_de/block/adapter.md index e588bc8030..6fe53a4124 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/adapter.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/adapter.md @@ -1,6 +1,6 @@ # Adapter -![Nun mit 100% mehr Alles!](oredict:oc:adapter) +![Nun mit 100% mehr Alles!](oredict:opencomputers:adapter) Der Adapter ermöglicht es [Computern](../general/computer.md) mit Vanilla-Minecraft-Blöcken oder Blöcken von anderen Mods zu interagieren. Unterstützte Blöcke neben dem Adapter werden als Komponenten des Computers aufgelistet. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/assembler.md b/src/main/resources/assets/opencomputers/doc/de_de/block/assembler.md index eb6f6d08a1..a845f24fdb 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/assembler.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/assembler.md @@ -1,6 +1,6 @@ # Elektronik-Werkbank -![Harder, better, faster, stronger.](oredict:oc:assembler) +![Harder, better, faster, stronger.](oredict:opencomputers:assembler) Die Elektronik-Werkbank ist eine fortgeschrittene Maschine welche verwendet werden kann, um komplexere elektronische Geräte wie [Roboter](robot.md), [Drohnen](../item/drone.md) oder [Tablets](../item/tablet.md) zu bauen. Sie benötigen eine große Menge an Energie um Geräte zu montieren, daher wird empfohlen, sie mittels einer [Kondensatorbank (capacitor bank)](capacitor.md) mit Energie zu versorgen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/cable.md b/src/main/resources/assets/opencomputers/doc/de_de/block/cable.md index 0316ae0e15..6d0044b160 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/cable.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/cable.md @@ -1,6 +1,6 @@ # Kabel -![Salat.](oredict:oc:cable) +![Salat.](oredict:opencomputers:cable) Das Kabel ist eine Möglichkeit, [Computer](../general/computer.md) und Maschinen, die weit auseinander stehen zu verbinden. Kompakte Bauten, bei denen sich alle Komponenten direkt oder indirekt berühren (die meisten Blöcke verhalten sich für Kabel) benötigen in der Regel keine Kabel. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/de_de/block/capacitor.md index 54f8a3b4e8..1d968d0000 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/capacitor.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/capacitor.md @@ -1,6 +1,6 @@ # Kondensator -![It's over 9000.](oredict:oc:capacitor) +![It's over 9000.](oredict:opencomputers:capacitor) Der Kondensator speichert Energie welche vom Netzwerk genutzt werden kann. Dadurch funktioniert es als Energiepuffer wenn es benötigt wird. Im Gegensatz zum Konvertieren von Energietypen anderer Mods (mittels eines [Energiekonverters](powerConverter.md)) erfolgt die Umwandlung von Energie innerhalb eines Subnetzwerkes ohne Verzögerung. Es ist nützlich, einen internen Energiepuffer für energieintensive Aufgaben (wie [Montage](assembler.md) oder das [Aufladen](charger.md) von Geräten wie [Robotern](robot.md) oder [Drohnen](../item/drone.md) zu haben. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/case1.md b/src/main/resources/assets/opencomputers/doc/de_de/block/case1.md index de68ea0afe..7c74e5eb53 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/case1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/case1.md @@ -1,6 +1,6 @@ # Computergehäuse -![Just in case.](oredict:oc:case1) +![Just in case.](oredict:opencomputers:case1) Computergehäuse gibt es in drei verschiedenen Stufen. Die Stufe bestimmt die maximale Anzahl an Komponenten, die eingesetzt werden können. Es gibt eine zusätzliche Stufe für den Kreativ-Modus. Gehäuse können ebenfalls in einer [Elektronik-Werkbank](assembler.md) platziert werden, um [Roboter](robot.md) zu bauen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/chameliumblock.md b/src/main/resources/assets/opencomputers/doc/de_de/block/chameliumblock.md index 92f1167937..8bd97f886d 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/chameliumblock.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/chameliumblock.md @@ -1,6 +1,6 @@ # Chamälium-Block -![So... nichtssagend...](oredict:oc:chameliumBlock) +![So... nichtssagend...](oredict:opencomputers:chameliumBlock) Einige Stücke [Chamälium](../item/chamelium.md) können kombiniert werden, um einen dekorativen Monochrom-Block zu schaffen. Chamäliumblöcke können mit einer der 16 Minecraft-Farben gefärbt werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/charger.md b/src/main/resources/assets/opencomputers/doc/de_de/block/charger.md index 747a5b1d44..755f87ddc7 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/charger.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/charger.md @@ -1,6 +1,6 @@ # Ladegerät -![Gehen wir es an!](oredict:oc:charger) +![Gehen wir es an!](oredict:opencomputers:charger) Das Ladegerät wird verwendet, um Geräte wie den [Roboter](robot.md), [Drohnen](../item/drone.md) und [Tablets](../item/tablet.md) zu laden. Ein Ladegerät muss mit einem Redstonesignal aktiviert werden. Die Ladegeschwindigkeit hängt von der Stärke des Redstonesignals ab. Eine Stärke von 15 bedeutet 100% Ladegeschwindigkeit. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/de_de/block/disassembler.md index 10bcece267..b5accf6b0f 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/disassembler.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/disassembler.md @@ -1,6 +1,6 @@ # Recycler -![Bau' es auf, reiß' es ab.](oredict:oc:disassembler) +![Bau' es auf, reiß' es ab.](oredict:opencomputers:disassembler) Der Recycler kann verwendet werden, um die meisten Items in ihre Bestandteile aufzuteilen. Dies ist besonders nützlich um Materialien von unnütz gewordenen Bauteilen zurückzubekommen, oder um Geräte zu demontieren, die nicht länger nützlich sind oder inkorrekt gebaut wurden (z.B. [Roboter](robot.md) ohne [Betriebssystem](../general/openOS.md)). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/diskdrive.md b/src/main/resources/assets/opencomputers/doc/de_de/block/diskdrive.md index 1317702848..8715aefd84 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/diskdrive.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/diskdrive.md @@ -1,6 +1,6 @@ # Diskettenlaufwerk -![Und das Rad dreht sich rundherum...](oredict:oc:diskDrive) +![Und das Rad dreht sich rundherum...](oredict:opencomputers:diskDrive) Das Diskettenlaufwerk kann verwendet werden, um [Disketten](../item/floppy.md) mittels eines Computers auszulesen. Dies ist am Anfang nützlich, da niedrigstufige [Computergehäuse](case1.md) keinen eingebauten Diskettenslot haben. Dennoch benötigst du ein Betriebssystem um den Computer hochzufahren. Eine [OpenOS](../general/openOS.md)-Diskette kann mit einer leeren [Diskette](../item/floppy.md) und dem [Handbuch](../item/manual.md) gefertigt werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/de_de/block/geolyzer.md index 7d3a6582ad..d48cacfce3 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/geolyzer.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/geolyzer.md @@ -1,6 +1,6 @@ # Geolyzer -![Er rockt!](oredict:oc:geolyzer) +![Er rockt!](oredict:opencomputers:geolyzer) Der Geolyzer kann von [Computern](../general/computer.md) verwendet werden, um das umgebende Terrain auf die ungefähre Härte von Blöcken zu analysieren. Dies ist nützlich um Karten der Gegend zu generieren, die auf einem [Hologrammprojektor](hologram1.md) angezeigt werden. Erze sind üblicherweise härter als Erde und Stein, daher kann man mit dem Geolyzer potenziell wertvolle Blöcke finden. Die Ergebnisse sind in der Regel etwas ungenau, theoretisch können mehrere Scans zu genaueren Ergebnissen führen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/de_de/block/hologram1.md index 990192f466..48ad70c42e 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/hologram1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/hologram1.md @@ -1,6 +1,6 @@ # Hologrammprojektor -![Is this the real life? Is this just fantasy?](oredict:oc:hologram1) +![Is this the real life? Is this just fantasy?](oredict:opencomputers:hologram1) Der Hologrammprojektor ist ein 3D-Display, das bedeutet es stellt ein dreidimensionales Array von "Voxeln" bereit, die von einem Computer einzeln aktiviert oder deaktiviert können. Der Stufe-2-Projektor hat dieselbe Auflösung, unterstützt allerdings die Darstellung in drei verschiedenen Farben. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/de_de/block/keyboard.md index 27046aa4a9..dbf54146b7 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/keyboard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/keyboard.md @@ -1,6 +1,6 @@ # Tastatur -![QWERTY](oredict:oc:keyboard) +![QWERTY](oredict:opencomputers:keyboard) Eine Tastatur wird benötigt um Text auf [Bildschirme](screen1.md) zu schreiben, egal ob in der Welt platziert oder in Geräte eingebaut (wie bei [Robotern](robot.md) oder [Tablets](../item/tablet.md)). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/motionsensor.md b/src/main/resources/assets/opencomputers/doc/de_de/block/motionsensor.md index 0da1a476f3..3a2073c73e 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/motionsensor.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/motionsensor.md @@ -1,6 +1,6 @@ # Bewegungssensor -![Nicht. Blinzeln.](oredict:oc:motionSensor) +![Nicht. Blinzeln.](oredict:opencomputers:motionSensor) Der Bewegungssensor erlaubt es [Computern](../general/computer.md) Bewegungen von lebenden Entities zu erkennen. Wenn die Geschwindigkeit eines Lebewesens einen Schwellenwert überschreitet wird ein Signal zum angeschlossenen Computer gesendet. Der Schwellwert kann mittels der Komponenten-API welche der Bewegungssensor bereitstellt verändert werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/netsplitter.md b/src/main/resources/assets/opencomputers/doc/de_de/block/netsplitter.md index d9b2dbb477..d06dc6c550 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/netsplitter.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/netsplitter.md @@ -1,6 +1,6 @@ # Net Splitter -![*.net *.split](oredict:oc:netSplitter) +![*.net *.split](oredict:opencomputers:netSplitter) Der Net Splitter ist ein Gerät das eine Kontrolle der Verbindungen zwischen Subnetzwerken ermöglicht. Im Gegensatz zum [Switch](switch.md) oder dem [Energiekonverter](powerConverter.md) verbindet es benachbarte Subnetzwerke direkt, das bedeutet, dass auf Komponenten zugegriffen werden kann. Die Verbindungen zu jeder Seite kann mit einem Schraubenschlüssel eingestellt werden (zum Beispiel den [srench](../item/wrench.md)). Wenn ein Redstonesignal an den Netzwerksplitter gesendet wird, werden alle Seiten invertiert. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/powerconverter.md b/src/main/resources/assets/opencomputers/doc/de_de/block/powerconverter.md index 5de9f9e6d1..c92f4d3836 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/powerconverter.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/powerconverter.md @@ -1,5 +1,5 @@ # Leistungswandler -![Einer von uns? Einer von uns!](oredict:oc:powerConverter) +![Einer von uns? Einer von uns!](oredict:opencomputers:powerConverter) Der Leistungswandler stellt den schnellsten Weg dar, um Energie von anderen Mods zu OpenComputers eigenem Energiesystem zu konvertieren. Wenn nur ein Computer verwendet wird, wird dieser nicht nötig sein. Bei einer großen Kondensatorbank, die nur dann und wann geleert wird, ist er ebenfalls nicht nötig. Wenn hingegen eine [Elektronik-Werkbank](assembler.md) oder eine [Ladestation](charger.md) direkt mit Energie versorgt werden soll, ist es eine gute Idee, diesen Konverter zu verwenden, anstatt sie direkt zu einer externen Energiequelle anzuschließen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/powerdistributor.md b/src/main/resources/assets/opencomputers/doc/de_de/block/powerdistributor.md index 192d90725c..796a1e6757 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/powerdistributor.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/powerdistributor.md @@ -1,5 +1,5 @@ # Stromverteiler -![Power to the masses.](oredict:oc:powerDistributor) +![Power to the masses.](oredict:opencomputers:powerDistributor) Der Stromverteiler verteilt Energie in einem geteilten Energiespeicher (wie beispielsweise in einem [Kondensator](capacitor.md). Dadurch können verschiedene Subnetzwerke dieselbe Energiequelle verwenden ohne Komponenten sichtbar zu machen. Es balanciert die Energie in allen Subnetzwerken aus, sodass sie alle die selbe relative Menge an Energie haben. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/printer.md b/src/main/resources/assets/opencomputers/doc/de_de/block/printer.md index 5bcb842475..bfec00fa32 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/printer.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/printer.md @@ -1,6 +1,6 @@ # 3D-Drucker -![2D printing is so yesteryear.](oredict:oc:printer) +![2D printing is so yesteryear.](oredict:opencomputers:printer) 3D-Drucker erlauben es, Blöcke von jeder Form mit jeder Art von Textur zu drucken. Um mit 3D-Druckern anzufangen wird ein 3D-Drucker und ein Computer benötigt. Dadurch erhält man Zugriff auf die `printer3d`-Komponenten-API. Hiermit können [Modelle](print.md) erstellt und gedruckt werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/raid.md b/src/main/resources/assets/opencomputers/doc/de_de/block/raid.md index 586b067c1d..ead8ba3b34 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/raid.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/raid.md @@ -1,6 +1,6 @@ # RAID -![40 man instance.](oredict:oc:raid) +![40 man instance.](oredict:opencomputers:raid) Der RAID-Block enthält drei [Festplatten](../item/hdd1.md), welche zu einem einzelnen Dateisystem kombiniert werden. Dieses einzelne Dateisystem hat als Kapazität die Summe der einzelnen Kapazitäten. Das Dateisystem kann mit allen angeschlossenen [Computern](../general/computer.md) verwendet werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/redstone.md b/src/main/resources/assets/opencomputers/doc/de_de/block/redstone.md index eafa6bc0fd..3bb9812fe1 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/redstone.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/redstone.md @@ -1,6 +1,6 @@ # Redstone-I/O -![Hi Red.](oredict:oc:redstone) +![Hi Red.](oredict:opencomputers:redstone) Der Redstone-I/O-Block kann verwendet werden, um ferngesteuert Redstonesignale auszugeben und einzulesen. Es verhält sich wie ein Hybrid einer Stufe-1- und einer Stufe-2-[Redstonekarte](../item/redstoneCard1.md). Es kann analoge und gebündelte Signale lesen wie schreiben, aber kann keine kabellosen Redstonesignale ausgeben. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/relay.md b/src/main/resources/assets/opencomputers/doc/de_de/block/relay.md index e2842edd65..3650db3194 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/relay.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/relay.md @@ -1,6 +1,6 @@ # Relay -![Baut Brücken.](oredict:oc:relay) +![Baut Brücken.](oredict:opencomputers:relay) Das Relay kann verwendet werden um verschiedene Subnetzwerken das Senden von Nachrichten zueinander zu ermöglichen, ohne Komponenten Computern in anderen Netzen zugänglich zu machen. Grundsätzlich ist es eine gute Idee Komponenten lokal zu behalten, damit [Computer](../general/computer.md) nicht die falschen Komponenten ansprechen oder Komponenten-Overflows zu verursachen (welche dazu führen, dass Computer crashen und nicht hochfahren.) diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/screen1.md b/src/main/resources/assets/opencomputers/doc/de_de/block/screen1.md index 4ad4be4fef..e7dab91e4c 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/screen1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/screen1.md @@ -1,6 +1,6 @@ # Bildschirme -![Kannst du das sehen?](oredict:oc:screen1) +![Kannst du das sehen?](oredict:opencomputers:screen1) Ein Bildschirm wird in Kombinationen mit [Grafikkarten](../item/graphicsCard1.md) verwendet, um mit [Computern](../general/computer.md) Text darzustellen. Verschiedene Stufen haben unterschiedliche Fähigkeiten, wie die Unterstützung verschiedener Auflösungen und Farbtiefen. Sie reichen von geringauflösenden Monochromdisplays zu hochauflösenden Displays mit bis zu 256 Farben. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/serverrack.md b/src/main/resources/assets/opencomputers/doc/de_de/block/serverrack.md index b7125eb7e6..575cfd1da6 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/serverrack.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/serverrack.md @@ -1,6 +1,6 @@ # Serverschrank -![Free housing.](oredict:oc:serverRack) +![Free housing.](oredict:opencomputers:serverRack) Ein Serverschrank kann bis zu vier [Server](../item/server1.md) enthalten. Ein Server ist ein höherstufiger [Computer](../general/computer.md) welcher nur in einem Serverschrank laufen kann. Server können mit einer [Fernbedienung](../item/terminal.md) ferngesteuert werden. Die Anzahl der Terminals die gleichzeitig mit einem Server verbunden werden können wird von der Stufe des Servers begrenzt. Der Abstand zum Server, bis zu dem das Terminal funktioniert kann in der GUI des Serverschranks konfiguriert werden. Mehr Reichweite bedeutet mehr Energieverbrauch. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/block/waypoint.md b/src/main/resources/assets/opencomputers/doc/de_de/block/waypoint.md index 26a4e24306..b8b23003fa 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/block/waypoint.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/block/waypoint.md @@ -1,6 +1,6 @@ # Wegpunkt -!["Da lang!" - "Nein, ganz falsch! Dort entlang!"](oredict:oc:waypoint) +!["Da lang!" - "Nein, ganz falsch! Dort entlang!"](oredict:opencomputers:waypoint) Der Wegpunkt kann mit Hilfe des [Navigations-Upgrades](../item/navigationUpgrade.md) erkannt werden. So können Geräte mit diesem Upgrade Wegpunkte verwenden um durch die Welt zu navigieren. Dies ist besonders nützlich zum Schreiben einfach wiederverwendbarer Programme für Geräte wie [Roboter](robot.md) und [Drohnen](../item/drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/de_de/general/quickstart.md index e3e9766a0f..88225bed43 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/general/quickstart.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/general/quickstart.md @@ -6,7 +6,7 @@ Auch bekannt als "Wie man seinen ersten Computer baut". Um deinen ersten [Comput Zuerst wirst du ein [Computergehäuse](../block/case1.md) benötigen. Dies sit der Block der alle Komponenten benötigt und das Verhalten des gebauten Computers bestimmen. -![Ein Stufe-2-Computergehäuse.](oredict:oc:case2) +![Ein Stufe-2-Computergehäuse.](oredict:opencomputers:case2) Zum Beispiel musst du bestimmen, welche Stufe die [Grafikkarte](../item/graphicsCard1.md) du benötigst, ob eine [Netzwerkkarte](../item/lanCard.md) oder eine [Redstonekarte](../item/redstoneCard1.md) benötigt wird oder, wenn du im Creative-Mode spielst, eine [Debugkarte](../item/debugCard.md) gebraucht wird. @@ -38,7 +38,7 @@ Wenn du, wie in den Screenshots oben, ein Stufe-2-Gehäuse verwendet hast gibt e Es lebt! Zumindest sollte es das. Wenn es das nicht tut lief etwas falsch, und das [Analysegerät](../item/analyzer.md) wird bei der Fehlersuche helfen. Wenn der Computer jetzt läuft bist zu weitgehend fertig und der schwerste Teil ist vorbei. Du musst es nur noch mit einem Um die Ausgabe des Computers zu lesen wird ein [Bildschirm](../block/screen1.md) und eine Grafikkarte benötigt. -![Nein. Es ist kein Flachbildschirm](oredict:oc:screen2) +![Nein. Es ist kein Flachbildschirm](oredict:opencomputers:screen2) Platziere den Bildschirm entweder direkt neben den Computer oder verbinde sie mit einem Kabel. Setze eine Grafikkarte deiner Wahl in den Computer ein. Nun sollte ein blinkender Cursor auf dem Bildschirm sichtbar sein. Jetzt fehlt nur noch eine [Tastatur](../block/keyboard.md) entweder direkt auf dem Bildschirm oder neben dem Bildschirm (mit Ausrichtung auf diesen). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/abstractbuscard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/abstractbuscard.md index 5807e0ae59..e47a712465 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/abstractbuscard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/abstractbuscard.md @@ -1,5 +1,5 @@ # Abstrakter-Bus-Karte -![Mehr Netzwerktechnik!](oredict:oc:abstractBusCard) +![Mehr Netzwerktechnik!](oredict:opencomputers:abstractBusCard) Diese Karte erlaubt es [Computern](../general/computer.md), [Servern](server1.md) und [Robotern](../block/robot.md) mit Abstract Busses von StargateTech2 zu interagieren. Wenn die Karte installiert ist, werden sich die entsprechenden Blöcke mit dem abstrakten Bus verbinden und eine Komponente wird für die Maschine sichtbar. Damit können Nachrichten über den Bus gesendet werden. Hereinkommende Nachrichten werden in Signale konvertiert und zur Maschine gesendet. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/acid.md b/src/main/resources/assets/opencomputers/doc/de_de/item/acid.md index f9af47bc2f..f037d67c67 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/acid.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/acid.md @@ -1,5 +1,5 @@ # Grog -![Reflux?](oredict:oc:materialAcid) +![Reflux?](oredict:opencomputers:materialAcid) Wird nur bei Hard-Mode-Rezepten verwenden. Es ist verwendet um [Leiterplatten](circuitBoard.md) zu ätzen, bevor sie zu [gedruckten Leiterplatten](printedCircuitBoard.md) werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/alu.md b/src/main/resources/assets/opencomputers/doc/de_de/item/alu.md index 485b93f6eb..39c6d115f6 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/alu.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/alu.md @@ -1,5 +1,5 @@ # Arithmetic Logic Unit -![Ich of logiks !](oredict:oc:materialALU) +![Ich of logiks !](oredict:opencomputers:materialALU) Wird für rechnende Komponenten wie [CPUs](cpu1.md) und [Grafikkarten](graphicsCard1.md) benötigt. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/de_de/item/analyzer.md index ac436f7bf3..9b16a5c3a5 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/analyzer.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/analyzer.md @@ -1,6 +1,6 @@ # Messgerät -![Hat nichts mit Kirche zu tun.](oredict:oc:analyzer) +![Hat nichts mit Kirche zu tun.](oredict:opencomputers:analyzer) Das Messgerät ist ein nützliches Werkzeug um OpenComputers-Geräte auszulesen. Mittels eines Rechtsklickes (ggf. auch beim Schleichen) werden die Informationen in den Chatlog geschrieben. Darunter fallen grundlegende Dinge wie die Adresse von Komponenten, den Energiemassen im Subnetzwerk bis zu Informationen über einen Crash. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/angelupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/angelupgrade.md index 6fff45b40a..b1d03bf383 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/angelupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/angelupgrade.md @@ -1,5 +1,5 @@ # Engels-Upgrade -![Hallelujah.](oredict:oc:angelUpgrade) +![Hallelujah.](oredict:opencomputers:angelUpgrade) Dieses Upgrade ermöglicht es [Robotern](../block/robot.md) Blöcke mitten in die Luft zu platzieren. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/apu1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/apu1.md index e473727a61..de11a79b34 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/apu1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/apu1.md @@ -1,6 +1,6 @@ # Beschleunigter Prozessor (APU) -![Ausgereiftesteste Physik United.](oredict:oc:apu1) +![Ausgereiftesteste Physik United.](oredict:opencomputers:apu1) APUs sind eine Mischung aus [CPUs](cpu1.md) und [Grafikkarten](graphicsCard1.md). Diese zu nutzen ermöglicht es einen Kartenslot mehr zu verwenden. Wie eine normale CPU definiert es die Architektur des [Computers](../general/computer.md) und die Nummer der Komponenten die verwendet werden können. Es ermöglicht zudem auch grundlegende Grafikberechnungen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/arrowkeys.md b/src/main/resources/assets/opencomputers/doc/de_de/item/arrowkeys.md index ef3b92bf4d..31dbafbc09 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/arrowkeys.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/arrowkeys.md @@ -1,5 +1,5 @@ # Pfeiltasten -![Sei nur froh, dass die nicht aus echten Pfeilen hergestellt werden..](oredict:oc:materialArrowKey) +![Sei nur froh, dass die nicht aus echten Pfeilen hergestellt werden..](oredict:opencomputers:materialArrowKey) Pfeiltasten sind nötig um [Tastaturen](../block/keyboard.md) zu bauen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/batteryupgrade1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/batteryupgrade1.md index 432d48289f..23c549b56b 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/batteryupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/batteryupgrade1.md @@ -1,5 +1,5 @@ # Batterie-Upgrade -![Aus Metall angefertigt.](oredict:oc:batteryUpgrade1) +![Aus Metall angefertigt.](oredict:opencomputers:batteryUpgrade1) Dieses Upgrade erhöht den internen Energiespeicher von Geräten wie [Robotern](../block/robot.md) und [Tablets](tablet.md). Sie können damit länger verwendet werden, bevor sie mit einem [Ladegerät](../block/charger.md) geladen werden müssen. Hochstufige Upgrades haben mehr Batteriekapazität. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/buttongroup.md b/src/main/resources/assets/opencomputers/doc/de_de/item/buttongroup.md index d6320600d0..348e9b7c21 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/buttongroup.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/buttongroup.md @@ -1,5 +1,5 @@ # Tastengruppe -![MOAR KNÖPFE.](oredict:oc:materialButtonGroup) +![MOAR KNÖPFE.](oredict:opencomputers:materialButtonGroup) Weil du *immer* zu viele Knöpfe hast. Lüg nicht! Wir Shift-Klicken das Tastenrezept immer und immer wieder. Die Gruppen werden um Bauen von [Tastaturen](../block/keyboard.md) verwendet. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/card.md b/src/main/resources/assets/opencomputers/doc/de_de/item/card.md index b7fa57fcf9..31e29df1f7 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/card.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/card.md @@ -1,5 +1,5 @@ # Karten -![Können nicht gelesen werden.](oredict:oc:materialCard) +![Können nicht gelesen werden.](oredict:opencomputers:materialCard) Übliches Ausgangsmaterial für kartenförmige Komponenten in OpenComputers (wie [Grafikkarten](graphicsCard1.md), [Netzwerkkarten](lanCard.md) usw.) diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/cardcontainer1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/cardcontainer1.md index 68791181be..143b3e36d0 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/cardcontainer1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/cardcontainer1.md @@ -1,5 +1,5 @@ # Kartenbehälter -![Ich kann Karten haben!!](oredict:oc:cardContainer1) +![Ich kann Karten haben!!](oredict:opencomputers:cardContainer1) Der Kartenbehälter ist ein Behälter-Upgrade für [Roboter](../block/robot.md) das es erlaubt, Karten in [Roboter](../block/robot.md) nach Bedarf einzusetzen oder zu entfernen. Die Stufe die eine Karte maximal haben darf gleicht der des Containers. Im Gegensatz zu normalen Upgrades ist die Komplexität das Doppelte seiner Stufe. Siehe [Komplexität](../block/robot.md). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/chamelium.md b/src/main/resources/assets/opencomputers/doc/de_de/item/chamelium.md index e0d5a9fdbc..3055969d0b 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/chamelium.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/chamelium.md @@ -1,6 +1,6 @@ # Chamälium -![Kommt vom Wort "Chamäleon".](oredict:oc:chamelium) +![Kommt vom Wort "Chamäleon".](oredict:opencomputers:chamelium) Chamälium ist ein formbares Material das für [3D-Drucke](../block/print.md) in [3D-Druckern](../block/printer.md) verwendet wird. Sonst ist es nutzlos und damit sehr nützlich um monochrome Bereiche zu erstellen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/chip1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/chip1.md index 5f8f5f20a8..6139510a17 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/chip1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/chip1.md @@ -1,5 +1,5 @@ # Microchips -![Nicht essbar.](oredict:oc:circuitChip1) +![Nicht essbar.](oredict:opencomputers:circuitChip1) Microchips sind die Grundlage für das Bauen von elektronischen Komponenten. Sie kommen in verschiedenen Stufen und ermöglichen unterschiedliche Komponentenstufen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/chunkloaderupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/chunkloaderupgrade.md index 634948efff..d1c700c453 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/chunkloaderupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/chunkloaderupgrade.md @@ -1,6 +1,6 @@ # Chunkloader-Upgrade -![Geht nirgendwo hin.](oredict:oc:chunkloaderUpgrade) +![Geht nirgendwo hin.](oredict:opencomputers:chunkloaderUpgrade) Das Chunkloader-Upgrade kann in Geräten wie [Robotern](../block/robot.md) oder [Mikrocontrollern](../block/microcontroller.md) installiert werden, um den Chunk in dem er sich befindet sowie umliegende Chunks geladen zu halten. Dies verbraucht jedoch Energie. Der Chunkloader kann mit der Komponenten-API ein- oder ausgeschaltet werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/circuitboard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/circuitboard.md index d0a3154a29..24d7116594 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/circuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/circuitboard.md @@ -1,5 +1,5 @@ # Leiterplatte -![Braucht mehr Gold.](oredict:oc:materialCircuitBoard) +![Braucht mehr Gold.](oredict:opencomputers:materialCircuitBoard) Zwischenitem das beim Herstellen von [bedruckten Leiterplatten](printedCircuitBoard.md) aus [rohen Leiterplatten](rawCircuitBoard.md) entsteht. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/componentbus1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/componentbus1.md index e60791f68e..b1d9bc22de 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/componentbus1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/componentbus1.md @@ -1,6 +1,6 @@ # Komponentenschnittstelle -![Fährt nirgendwo hin](oredict:oc:componentBus1) +![Fährt nirgendwo hin](oredict:opencomputers:componentBus1) Eine Komponentenschnittstelle ist ein [Server](server1.md)spezifisches Upgrade das es dem Server erlaubt, mit mehr Komponenten auf einmal zu kommunizieren ohne sich abzuschalten. Wie bei [CPUs](cpu1.md) auch ermöglichen höhere Stufen mehr Komponenten und höhere Stufen für Server ermöglichen mehr Slots für Komponentenschnittstellen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/controlunit.md b/src/main/resources/assets/opencomputers/doc/de_de/item/controlunit.md index 1b270e19a2..7a0af554f6 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/controlunit.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/controlunit.md @@ -1,5 +1,5 @@ # Kontrolleinheit -![Mit eingebauter Cruising-Funktion.](oredict:oc:materialCU) +![Mit eingebauter Cruising-Funktion.](oredict:opencomputers:materialCU) Hochstufiges Craftingitem in weiter entwickelten Schaltkreisen wie [CPUs](cpu1.md). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/cpu1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/cpu1.md index 3fb63ace8e..b73671cc2d 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/cpu1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/cpu1.md @@ -1,6 +1,6 @@ # CPU -![Gehirrrrrn.](oredict:oc:cpu1) +![Gehirrrrrn.](oredict:opencomputers:cpu1) Die zentrale Recheneinheit ist das Herz eines jeden [Computers](../general/computer.md) oder [Servers](server1.md). Sie definiert die Architektur des Gerätes und die Anzahl der Komponenten die maximal mit dem Gerät verbunden werden können bevor er zu funktionieren aufhört. Hochstufige CPUs ermöglich außerdem eine schnellere Ausführung. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/craftingupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/craftingupgrade.md index 806130c2a3..b270bba85d 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/craftingupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/craftingupgrade.md @@ -1,5 +1,5 @@ # Crafting-Upgrade -![Kräftig.](oredict:oc:craftingUpgrade) +![Kräftig.](oredict:opencomputers:craftingUpgrade) Das Crafting-Upgrade erlaubt [Robotern](../block/robot.md) jede Art von Rezepten zu fertigen. Dabei werden Items aus dem [Inventar](../item/inventoryUpgrade.md) verwendet. Das 3x3-Netz im Inventar des Roboters wird als Werkbank verwendet. Items müssen entsprechend dem Rezept angeordnet sein. Ergebnisse werden im gewählten Slot im Inventar oder im nächsten freien Slot abgelegt, oder in die Welt geworfen, wenn kein Platz mehr übrig ist. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/cuttingwire.md b/src/main/resources/assets/opencomputers/doc/de_de/item/cuttingwire.md index 88e76beffa..d8cdd040e9 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/cuttingwire.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/cuttingwire.md @@ -1,5 +1,5 @@ # Schneidedraht -![Kein Würgedraht. Wirklich.](oredict:oc:materialCuttingWire) +![Kein Würgedraht. Wirklich.](oredict:opencomputers:materialCuttingWire) Dieses Item wird nur im Hard-Mode-Rezept für [Leiterplattenrohlinge](rawCircuitBoard.md) verwendet. Ineffektiv. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/databaseupgrade1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/databaseupgrade1.md index 6cc5e5d852..867280cb4e 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/databaseupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/databaseupgrade1.md @@ -1,6 +1,6 @@ # Datenbank-Upgrade -![Living in the database.](oredict:oc:databaseUpgrade1) +![Living in the database.](oredict:opencomputers:databaseUpgrade1) Das Datenbank-Upgrade kann konfiguriert werden um eine Liste von Itemstack-Repräsentationen zu speichern. Die können von anderen Komponenten verwendet werden. Das ist besonders nützlich für Items die mit ihren NBT-Daten sortiert werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/datacard1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/datacard1.md index 6812b2cbb5..e1a4f70215 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/datacard1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/datacard1.md @@ -1,6 +1,6 @@ # Datenkarte -![Im Gegensatz zum allgemeinen Glauben speichert das keine Daten.](oredict:oc:dataCard1) +![Im Gegensatz zum allgemeinen Glauben speichert das keine Daten.](oredict:opencomputers:dataCard1) Die Datenkarte ist eine Werkzeugkarte die einige Algorithmen zur Verfügung stellen die nur sehr schlecht oder sehr langsam implementierbar wären. Möglich ist Hashing und grundlegendes Inflating und Deflating.. Zudem enthält es ein angefügtes Dateisystem und stellt eine Vielzahl von Programmen zur Verfügung die die Funktionen der Karte verwenden, ähnlich der Internetkarte. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/debugcard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/debugcard.md index 2e7cd6dae7..0cc40e7999 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/debugcard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/debugcard.md @@ -1,6 +1,6 @@ # Debugkarte -![Warte - Wenn ich... oooooh.](item:OpenComputers:item@73) +![Warte - Wenn ich... oooooh.](item:opencomputers:debugcard) Die Debugkarte ist ein Nur-Kreativ-Item das ursprünglich entwickelt wurde, um einige Vorgänge zu vereinfachen in dem sie einige Prozesse automatisieren. Es hat seitdem eine Vielfalt an Zusatzfunktionen erhalten. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/disk.md b/src/main/resources/assets/opencomputers/doc/de_de/item/disk.md index e29167ac9a..4cf56b596d 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/disk.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/disk.md @@ -1,5 +1,5 @@ # Speicherplatte -![World. RIP Terry Pratchett.](oredict:oc:materialDisk) +![World. RIP Terry Pratchett.](oredict:opencomputers:materialDisk) Grundlegende Komponente, die zum Bau von Speichermedien wie [Disketten](floppy.md) und [Festplatten](hdd1.md) benötigt wird. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/drone.md b/src/main/resources/assets/opencomputers/doc/de_de/item/drone.md index 81a24f77ad..4e1bda25dd 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/drone.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/drone.md @@ -1,5 +1,5 @@ # Drohne -![Hat nichts mit der NSA zu tun..](item:OpenComputers:item@84) +![Hat nichts mit der NSA zu tun..](item:opencomputers:drone) Drohnen werden mit einem [Drohnengehäuse](droneCase1.md) in der [Elektronik-Werkbank](../block/assembler.md) gebaut. Sie sind entitybasierende [Roboter](../block/robot.md), allerdings ein bisschen günstiger und mit eingeschränkter Funktionalität. Sie können sich zudem weitaus schneller bewegen als [Roboter](../block/robot.md) und werden über ein Clientprogramm auf einem Computer gesteuert. Die Drohne benötigt ein konfiguriertes [EEPROM](eeprom.md) um Befehle zu empfangen oder selbst zu arbeiten. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/dronecase1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/dronecase1.md index 01c4d37793..d4911b1a59 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/dronecase1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/dronecase1.md @@ -1,6 +1,6 @@ # Drohnengehäuse -![Droning on.](oredict:oc:droneCase1) +![Droning on.](oredict:opencomputers:droneCase1) Das Drohnengehäuse wird verwendet um [Drohnen](drone.md) in der [Elektronik-Werkbank](../block/assembler.md) zu bauen. Drohnen sind leicht, schnell und sehr mobil, haben jedoch einen eingeschränkten Funktionenszeitraum (d.h. weniger Upgrade- und Komponentenslots sind verfügbar). Im Gegensatz zu [Robotern](../block/robot.md) können sie keine Werkzeuge verwenden und können nur indirekt mit der Welt interagieren. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/eeprom.md b/src/main/resources/assets/opencomputers/doc/de_de/item/eeprom.md index 29953d1084..d051f64030 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/eeprom.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/eeprom.md @@ -1,6 +1,6 @@ # EEPROM -![Let's get this party started.](oredict:oc:eeprom) +![Let's get this party started.](oredict:opencomputers:eeprom) Der EEPROM enthält den Code der verwendet wird um den Computer zu starten. Diese Daten sind als einfaches Bytearray gespeichert und können bei unterschiedlichen Architekturen andere Operationen auslösen. Das LUA-BIOS ist ein kleines Script das auf dem Dateisystem nach eine Datei namens `init.lua`. Auf anderen Architekturen kann es echter Maschinencode sein. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/experienceupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/experienceupgrade.md index 2228289a2e..fed97371fe 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/experienceupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/experienceupgrade.md @@ -1,6 +1,6 @@ # Erfahrungs-Upgrade -![Kaum sinnvoll, sehr cool.](oredict:oc:experienceUpgrade) +![Kaum sinnvoll, sehr cool.](oredict:opencomputers:experienceUpgrade) Das Erfahrungs-Upgrade ist ein sehr spezielles Upgrade, da es [Robotern](../block/robot.md) und [Drohnen](drone.md) ermöglicht, Erfahrung zu sammeln. Ein einziges Upgrade kann bis zu 30 Level speichern und ermöglicht damit kleinere Boni, wie schnellere Ausführung oder erhöhte Energiespeicherkapazität. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/floppy.md b/src/main/resources/assets/opencomputers/doc/de_de/item/floppy.md index 945ee14a22..94e5ad504e 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/floppy.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/floppy.md @@ -1,5 +1,5 @@ # Diskette -![Klobig](oredict:oc:floppy) +![Klobig](oredict:opencomputers:floppy) Die Diskette ist das günstigste und kleinste Speichermedium in OpenComputers. Es ist ein nützliches Item für das frühe Spiel um Daten zwischen den Geräten zu transferieren. Disketten mit nützlichen Programmen können in Dungeons gefunden werden (wie der OpenPrograms Package Manager, womit Programme von einem zentralen Github-Repository installiert werden können.) diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/generatorupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/generatorupgrade.md index 3672b0a049..8958a14b5e 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/generatorupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/generatorupgrade.md @@ -1,6 +1,6 @@ # Generator-Upgrade -![Generator X.](oredict:oc:generatorUpgrade) +![Generator X.](oredict:opencomputers:generatorUpgrade) Das Generator-Upgrade ermöglicht es Geräten sich im Betrieb neu aufzuladen. Zurzeit werden nur trockene Energiequellen (wie Kohle) unterstützt. Es hat ein internes Inventar welches ein Stack an Energiequellen halten kann. Überflüssige Energiequellen können über die Komponenten-API entfernt werden. Ein Upgrade von einem Roboter zu entfernen führt dazu, dass der Inhalt in die Welt geworfen wird. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/graphicscard1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/graphicscard1.md index 770922a49b..f49dff83af 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/graphicscard1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/graphicscard1.md @@ -1,6 +1,6 @@ # Grafikkarten -![Schicke Bilder.](oredict:oc:graphicsCard1) +![Schicke Bilder.](oredict:opencomputers:graphicsCard1) Die Grafikkarte ist essenziell für die meisten [Computer](../general/computer.md). Damit können sie Text auf einem verbundenen [Bildschirm](../block/screen1.md) darstellen. Grafikkarten kommen in verschiedenen Stufen, die zusammen mit dem Bildschirm unterschiedliche Auflösungen und Farbtiefen unterstützen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/hdd1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/hdd1.md index 97473bf80e..9791371a83 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/hdd1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/hdd1.md @@ -1,5 +1,5 @@ # Festplatte -![01010011 01110000 01100001 01100011 01100101.](oredict:oc:hdd1) +![01010011 01110000 01100001 01100011 01100101.](oredict:opencomputers:hdd1) Die Festplatten haben mehr Speicherplatz als andere OpenComputers-Speichermedien. Alle Medien arbeiten gleich schnell, haben allerdings unterschiedliche Speicherplatzgrößen. Es gibt auch Geräte die nur Disketten verwenden. Festplatten können in einem [RAID](../block/raid.md) platziert werden, um Geräten das Teilen des selben Dateisystems zu ermöglichen. Wenn eine Festplatte in einem RAID platziert werden, werden allerdings die Daten gelöscht. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/hoverboots.md b/src/main/resources/assets/opencomputers/doc/de_de/item/hoverboots.md index 091a40e357..4636704fd8 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/hoverboots.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/hoverboots.md @@ -1,6 +1,6 @@ # Schwebestiefel -![Tritt drauf!](oredict:oc:hoverBoots) +![Tritt drauf!](oredict:opencomputers:hoverBoots) Drohnen zu programmieren kann eine lange Zeit dauern. Es gibt allerdings eine Alternative dazu: Schwebestiefel. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/hoverupgrade1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/hoverupgrade1.md index f19dc925f6..a35ee0a35d 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/hoverupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/hoverupgrade1.md @@ -1,6 +1,6 @@ # Schwebe-Upgrade -![Leicht wie eine Feder.](oredict:oc:hoverUpgrade1) +![Leicht wie eine Feder.](oredict:opencomputers:hoverUpgrade1) Das Schwebe-Upgrade erlaubt es [Robotern](../block/robot.md) viel höher über dem Boden zu fliegen als normal. Im Gegensatz zu [Drohnen](drone.md) können diese nämlich standardmäßig nur 8 Block hoch schweben. Das ist normal kein großes Problem, da sie sich trotzdem an Wänden entlang bewegen können. Sie können sich so bewegen: - Roboter können sich nur bewegen, wenn Start- und Zielposition gültig sind (z.B. um Brücken bauen zu können) diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/inkcartridge.md b/src/main/resources/assets/opencomputers/doc/de_de/item/inkcartridge.md index d7655b3ab4..f17c0388eb 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/inkcartridge.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/inkcartridge.md @@ -1,5 +1,5 @@ # Tintenkartusche -![Regenbogenfarbig.](oredict:oc:inkCartridge) +![Regenbogenfarbig.](oredict:opencomputers:inkCartridge) Tintenkartuschen sind nützlich um den Farbbuffer von [3D-Druckern·](../block/printer.md) zu füllen. Es ist auch möglich sie mit Farbmitteln direkt zu färben, das ist aber ineffizient. Am besten kaufen Sie noch heute die echten OC Tintenfarben (TM) heute! (Disclaimer: Unter Umständen könnten sie mehr als der Drucker selbst kosten.) diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/internetcard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/internetcard.md index 5d36d5c30e..defb260596 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/internetcard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/internetcard.md @@ -1,6 +1,6 @@ # Internetkarte -![Katzenvideos in 3, 2,....](oredict:oc:internetCard) +![Katzenvideos in 3, 2,....](oredict:opencomputers:internetCard) Internetkarten bieten [Computern](../general/computer.md) Internetzugriff. Einfache HTTP-Anfragen sind möglich, sowie einfache TCP-Client-Sockets die gelesen und beschrieben werden können. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/interweb.md b/src/main/resources/assets/opencomputers/doc/de_de/item/interweb.md index 558b45f43b..9dfadb8974 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/interweb.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/interweb.md @@ -1,5 +1,5 @@ # Internetz -![A website is a place where there's cobweb.](oredict:oc:materialInterweb) +![A website is a place where there's cobweb.](oredict:opencomputers:materialInterweb) Das Internetz ist eine grundlegende Komponente für alle Geräte die mit Hochdistanzkommunikation zusammenhängen. Es nutzt verrückte Mechaniken des Ends um Quantenlinienkommunikation zu ermöglichen. Wird vor allem in [Internetkarten](internetCard.md) und [verknüpften Karten](linkedCard.md) verwendet. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/inventorycontrollerupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/inventorycontrollerupgrade.md index 90f1c1c663..2414f00291 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/inventorycontrollerupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/inventorycontrollerupgrade.md @@ -1,6 +1,6 @@ # Inventarbedienungs-Upgrade -![Ich bin unter Kontrolle.](oredict:oc:inventoryControllerUpgrade) +![Ich bin unter Kontrolle.](oredict:opencomputers:inventoryControllerUpgrade) Das Inventarbedienungs-Upgrade ermöglicht erweiterte Inventarinteraktionen für [Roboter](../block/robot.md) und [Drohnen](drone.md). Es erlaubt es dem Gerät explizit einzelne Slots in externen Inventaren zu verwenden. Es erlaubt es dem Gerät zudem detaillierte Informationen über seine Itemstacks zu lesen. Zuletzt stellt es Robotern eine Möglichkeit zur Verfügung, das Werkzeug ohne Hilfe zu wechseln. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/inventoryupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/inventoryupgrade.md index 94ca075c90..4954d5da89 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/inventoryupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/inventoryupgrade.md @@ -1,6 +1,6 @@ # Inventar-Upgrade -![Wo legt es diesen ganzen Kram hin...](oredict:oc:inventoryUpgrade) +![Wo legt es diesen ganzen Kram hin...](oredict:opencomputers:inventoryUpgrade) Das Inventar-Upgrade stellt Inventarslots für [Roboter](../block/robot.md) und [Drohnen](drone.md) bereit. Jedes Upgrade fügt 16 Inventarslots hinzu, bis zu einem Maximum von 64 Slots. Eine Drohne fügt 4 Slots pro Upgrade hinzu, bis zu einem Maximum von 8 Slots. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/lancard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/lancard.md index 968a1840cf..dbbe8dddbd 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/lancard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/lancard.md @@ -1,5 +1,5 @@ # Netzwerkkarte -![Tritt ins Netzwerk ein.](oredict:oc:lanCard) +![Tritt ins Netzwerk ein.](oredict:opencomputers:lanCard) Die Netzwerkkarte erlaubt es [Computern](../general/computer.md), Nachrichten vom Netzwerk zu empfangen und zum Netzwerk zu senden. Nachrichten (oder Pakete) können über das ganze Netzwerk oder zu spezifischen Knotenpunkten mit einer bestimmten Adresse gesendet werden. [Switche](../block/switch.md) und [Access Points](../block/accessPoint.md) können verwendet werden, um verschiedene Netzwerke miteinander zu verbinden. Nachrichten können dann zwischen verschiedenen Netzwerken hin- und hergesendet werden, auch zwischen unterschiedlichen Subnetzwerken. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/leashupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/leashupgrade.md index e7d4090a6b..499acdb7f8 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/leashupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/leashupgrade.md @@ -1,5 +1,5 @@ # Leinen-Upgrade -![-Angeleint- ~ Vexatos 2015](oredict:oc:leashUpgrade) +![-Angeleint- ~ Vexatos 2015](oredict:opencomputers:leashUpgrade) Das Leinen-Upgrade ermöglicht es, Leinen auf Tiere anzulegen. Das entsprechende Gerät (zum Beispiel eine [Drohne](drone.md)) kann dann Tiere führen, auch mehrere auf einmal. Es ist damit recht einfach Herden zu bewegen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/linkedcard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/linkedcard.md index 7a8d0f030e..f205000474 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/linkedcard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/linkedcard.md @@ -1,5 +1,5 @@ # Verlinkte Karte -![Ich fühle eine Verbindung](oredict:oc:linkedCard) +![Ich fühle eine Verbindung](oredict:opencomputers:linkedCard) Die verlinkte Karte ist eine spezialisierte und fortgeschrittene Version einer [Netzwerkkarte](lanCard.md). Gelinkte Karten treten nur im Paar auf und ermöglichen eine direkte Kommunikation zwischen den beiden Karten. Gelinkte Karten können über unbegrenzt weite Distanzen und über Dimensionen hinweg kommunizieren. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/manual.md b/src/main/resources/assets/opencomputers/doc/de_de/item/manual.md index 994f086141..47724f5207 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/manual.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/manual.md @@ -1,6 +1,6 @@ # Handbuch -![Ein gutes Buch.](oredict:oc:manual) +![Ein gutes Buch.](oredict:opencomputers:manual) Das Ding das du gerade liest! Das Handbuch enthält eine Vielfalt von Informationen über OpenComputers (und vielleicht mehr). Wenn du mehr Informatonen über ein Item oder einen Block im Mod benötigst, bist du hier genau richtig! Scrolle herunter für mehr Informationen (Mausrad oder Scrollbar auf der rechten Seite). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/microcontrollercase1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/microcontrollercase1.md index 3cf502fa1d..0ce27dfccd 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/microcontrollercase1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/microcontrollercase1.md @@ -1,6 +1,6 @@ # Mikrocontroller-Gehäuse -![So niedlich!](oredict:oc:microcontrollerCase1) +![So niedlich!](oredict:opencomputers:microcontrollerCase1) Das Mikrocontroller-Gehäuse ist das grundlegende Teil zum Bau von [Mikrocontrollern](../block/microcontroller.md) in der [Elektronik-Werkbank](../block/assembler.md). Mikrocontroller sind sehr primitive [Computer](../general/computer.md). Sie können nur eine bestimmte Anzahl an Komponenten enthalten und sind für sehr spezifische Anwendungsfälle gedacht, wie das Reagieren auf Redstonesignale, oder das Verarbeiten von Netzwerknachrichten. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/navigationupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/navigationupgrade.md index f10a49b737..c0e3fe53e4 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/navigationupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/navigationupgrade.md @@ -1,6 +1,6 @@ # Navigations-Upgrade -![Ich habe mich verirrt. Schon. Wieder.](oredict:oc:navigationUpgrade) +![Ich habe mich verirrt. Schon. Wieder.](oredict:opencomputers:navigationUpgrade) Das Navigation-Upgrade stellt Informationen über den Standort und zur Orientierung bereit. Die Koordinaten, die das Upgrade zur Verfügung stellt sind relativ zum Zentrum der Karte, die zum Anfertigen des Upgrades verwendet wird. Die Reichweite des Upgrades basiert auf die Größe dieser Karte. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/numpad.md b/src/main/resources/assets/opencomputers/doc/de_de/item/numpad.md index 013e2ad12d..bc42a57348 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/numpad.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/numpad.md @@ -1,5 +1,5 @@ # Ziffernblock -![Prüfe es auf Fingerabdrücke.](oredict:oc:materialNumPad) +![Prüfe es auf Fingerabdrücke.](oredict:opencomputers:materialNumPad) Der Ziffernblock ist Teil einer jeden [Tastatur](../block/keyboard.md). Es erlaubt es, Zahlen einzugeben. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/pistonupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/pistonupgrade.md index 7f1861216e..d3bf89146d 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/pistonupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/pistonupgrade.md @@ -1,6 +1,6 @@ # Kolben-Upgrade -![Push it.](oredict:oc:pistonUpgrade) +![Push it.](oredict:opencomputers:pistonUpgrade) Das Kolben-Upgrade erlaubt es einigen Geräten, ähnlich wie Vanilla-Kolben zu arbeiten. Wenn es installiert ist, wird eine Komponente mit einer einzigen Methode verfügbar, der `push()`-Methode. Wenn sie aufgerufen wird, das Gerät versuchen, den Block in der Richtung zu verschieben, in die der Block zeigt. Bei [Robotern](../block/robot.md) und [Mikrocontrollern](../block/microcontroller.md) ist das die Vorderseite, bei [Tablets](tablets.md) ist das der Block auf den der Spieler schaut. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/printedcircuitboard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/printedcircuitboard.md index 37d78454a2..9dd7a54d56 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/printedcircuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/printedcircuitboard.md @@ -1,5 +1,5 @@ # Gedruckte Leiterplatte (PCB) -![AKA PCB](oredict:oc:materialCircuitBoardPrinted) +![AKA PCB](oredict:opencomputers:materialCircuitBoardPrinted) Die bedruckte Leiterplatte ist, neben dem [Transistor](transistor.md) eine der grundlegendsten Werkstoffe in OpenComputers. Es wird als Basis für viele Komponenten verwendet, wie [Karten](card.md) und eine große Anzahl an [Blöcken](../block/index.md). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/ram1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/ram1.md index e5e05ab231..5786345dea 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/ram1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/ram1.md @@ -1,6 +1,6 @@ # Speicher (RAM) -![Do you remember, dancing in September~](oredict:oc:ram1) +![Do you remember, dancing in September~](oredict:opencomputers:ram1) Der Random Access Memory ist, wie die [CPU](cpu1.md) ein grundlegendes Teil in allen [Computern](../general/computer.md). Je nach der Architektur der CPU hat der RAM einen großen Effekt darauf, was ein Computer kann und was er nicht kann. In der standardmäßigen LUA-Architektur kontrolliert es die tatsächliche Menge von Memory die LUA-Scripts verwenden können. Um größere und speicherintensivere Programme zu schreiben wird mehr Speicher verwendet. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/rawcircuitboard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/rawcircuitboard.md index ebdb1da2e1..017b799ff5 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/rawcircuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/rawcircuitboard.md @@ -1,5 +1,5 @@ # Leiterplattenrohling -![Nicht Sushi.](oredict:oc:materialCircuitBoardRaw) +![Nicht Sushi.](oredict:opencomputers:materialCircuitBoardRaw) Zwischenprodukt beim Fertigen. Wird verwendet, um [Leiterplatten](circuitBoard.md) (oder [gedruckte Leiterplatten](printedCircuitBoard.md), je nach dem welches Recipe-Set verwendet wird) zu fertigen. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/redstonecard1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/redstonecard1.md index b994efbbe0..b0a5bdd9a1 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/redstonecard1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/redstonecard1.md @@ -1,6 +1,6 @@ # Redstonekarte -![Sieht rot.](oredict:oc:redstoneCard1) +![Sieht rot.](oredict:opencomputers:redstoneCard1) Die Redstonekarte ermöglicht [Computern](../general/computer.md) das Lesen und Senden von analogen Redstonesignalen zu benachbarten Blöcken. Wenn sich ein eingehendes Signal ändert wird dies dem Computer gemeldet. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/server1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/server1.md index 26245e30fe..a1153aa485 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/server1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/server1.md @@ -1,6 +1,6 @@ # Server -![Serviert alles korrekt.](oredict:oc:server1) +![Serviert alles korrekt.](oredict:opencomputers:server1) Server sind eine Form von hochstufigen [Computern](../general/computer.md). Sie können mit Rechtsklick konfiguriert werden, wenn sie in der Hand liegen. Nach dem Einsetzen von [CPU](cpu1.md), [RAM](ram1.md) und Erweiterungskarten muss der Server in einem [Serverschrank](../block/serverRack.md) platziert werden. Für Informationen siehe [Eintrag des Serverschranks](../block/serverRack.md). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/signupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/signupgrade.md index 95101e687f..7281ef6d38 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/signupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/signupgrade.md @@ -1,5 +1,5 @@ # Schilder-I/O -![Sagt mehr als tausend Worte.](oredict:oc:signUpgrade) +![Sagt mehr als tausend Worte.](oredict:opencomputers:signUpgrade) Dieses Upgrade ermöglicht es Geräten mit Schildern in der Welt zu interagieren. Es erlaubt das Lesen von Schildern sowie das Ändern des Schildes (wenn möglich). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/solargeneratorupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/solargeneratorupgrade.md index 49fd11ae08..7339361206 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/solargeneratorupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/solargeneratorupgrade.md @@ -1,6 +1,6 @@ # Solargenerator-Upgrade -![Is walking on sunshine.](oredict:oc:solarGeneratorUpgrade) +![Is walking on sunshine.](oredict:opencomputers:solarGeneratorUpgrade) Das Solargenerator-Upgrade kann in Geräten wie [Robotern](../block/robot.md), [Drohnen](drone.md) und [Tablets](tablet.md) dazu verwendet werden, passiv Energie zu generieren. Es funktioniert nur, wenn das Gerät direktem Sonnenlicht ausgesetzt ist und keine Wetterereignisse stören. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/tablet.md b/src/main/resources/assets/opencomputers/doc/de_de/item/tablet.md index ca3ec45db0..b8339f353a 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/tablet.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/tablet.md @@ -1,6 +1,6 @@ # Tablet -![Berühr' mich, wenn du kannst.](item:OpenComputers:item@68) +![Berühr' mich, wenn du kannst.](item:opencomputers:tablet) Tablets werden gebaut, indem ein [Tabletgehäuse](tabletCase1.md) in einer [Elektronik-Werkbank](../block/assembler.md) eingesetzt, konfiguriert und montiert wird. Tablets sind tragbare Computer die nicht direkt mit der Welt interagieren können. Das bedeutet, dass beispielsweise [Redstonekarten](redstoneCard1.md) nicht darin funktionieren. Eine Vielfalt von Upgrades funktionieren schon, wie das [Schild-I/O](signUpgrade.md) oder das [Kolbenupgrade](pistonUpgrade.md). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/tabletcase1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/tabletcase1.md index 5c82c1b68d..4772f57fb2 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/tabletcase1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/tabletcase1.md @@ -1,6 +1,6 @@ # Tabletgehäuse -![Verbiegt sich nicht.](oredict:oc:tabletCase1) +![Verbiegt sich nicht.](oredict:opencomputers:tabletCase1) Das Tabletgehäuse ist das grundlegende Teil um [Tablets](tablet.md) in der [Elektronik-Werkbank](../block/assembler.md) zu bauen. Tablets sind sehr kompakte, tragbare [Computer](../general/computer.md). Sie können eine kleine Nummer von ausgewählten Upgrades halten und nicht mit der Welt interagieren (wie [Computergehäuse](../block/case1.md) mit [Netzwerkkarten](lanCard.md) oder [Redstonekarten](redstoneCard1.md) es können). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/tankcontrollerupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/tankcontrollerupgrade.md index f8bb5a9652..71dea2b6a8 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/tankcontrollerupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/tankcontrollerupgrade.md @@ -1,6 +1,6 @@ # Tankcontroller -![Flüssigrouting.](oredict:oc:tankControllerUpgrade) +![Flüssigrouting.](oredict:opencomputers:tankControllerUpgrade) Das Tankcontroller-Upgrade ist das [Inventarcontroller-Upgrade](inventoryControllerUpgrade.md) für Tanks. Es können detaillierte Informationen über Tanks abgefragt werden. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/tankupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/tankupgrade.md index 94dc204a3e..4c9fda0e25 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/tankupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/tankupgrade.md @@ -1,5 +1,5 @@ # Tank Upgrade -![Suck it.](oredict:oc:tankUpgrade) +![Suck it.](oredict:opencomputers:tankUpgrade) Das Tank-Upgrade ermöglicht es Geräten, Flüssigkeiten zu halten. Jeder Tank kann nur eine einzige Art von Flüssigkeit halten und stellt ein Volumen von 16 Eimern (16.000mB) zur Verfügung. [Roboter](../block/robot.md) und [Drohnen] können Flüssigkeiten aus der Welt aufnehmen und die Flüssigkeit dann in Tanks oder, wenn die Flüssigkeit das ermöglicht, wieder in der Welt platzieren. Es gibt kein Maximum an installierten Tanks in einem Gerät. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/terminal.md b/src/main/resources/assets/opencomputers/doc/de_de/item/terminal.md index 71f0712c33..407e5f1eee 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/terminal.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/terminal.md @@ -1,6 +1,6 @@ # Fernbedienungsterminal -![Fernzugriff.](oredict:oc:terminal) +![Fernzugriff.](oredict:opencomputers:terminal) Das Fernbedienungsterminal kann verwendet werden um [Server](server1.md) fernzusteuern. Um es zu verwenden reicht ein Rechtsklick (im Schleichen) auf einen Server in einem [Serverschrank](../block/serverRack.md). (Dabei muss auf den Server im Block gezeigt werden. Das Terminal wird dann auf den Server gebunden): diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/texturepicker.md b/src/main/resources/assets/opencomputers/doc/de_de/item/texturepicker.md index 881dbdf38b..aae7acfbc4 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/texturepicker.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/texturepicker.md @@ -1,6 +1,6 @@ # Texturleser -![Was soll das heißen, "das ist nur ein reskin"?](oredict:oc:texturePicker) +![Was soll das heißen, "das ist nur ein reskin"?](oredict:opencomputers:texturePicker) Der Texturleser ist sehr nützlich beim Anfertigen von Modellen für den [3D-Drucker](../block/printer.md). Es erlaubt das Abfragen der Texturnamen, die bei Blöcken in der Welt verwendet werden. Dies kann Probleme bei bestimmten Blöcken mit speziellem Rendering verursachen (wie z.B. bei Kisten) diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/tractorbeamupgrade.md b/src/main/resources/assets/opencomputers/doc/de_de/item/tractorbeamupgrade.md index 975e72b638..c68b312e46 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/tractorbeamupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/tractorbeamupgrade.md @@ -1,5 +1,5 @@ # Traktorstrahl-Upgrade -![Beam me up.](oredict:oc:tractorBeamUpgrade) +![Beam me up.](oredict:opencomputers:tractorBeamUpgrade) Das Traktorstrahl-Upgrade erlaubt es Geräten Items in einem Drei-Block-Radius um sie herum aufzusammeln. Dies kann besonders nützlich sein, wenn [Roboter](../block/robot.md) in Baum- oder anderen Farmen eingesetzt werden, oder wenn sie verschiedene Werkzeuge um Abbau von unterschiedlichen Blöcken einsetzen. Jeder Einsatz saugt einen einzelnen Itemstack auf und verbraucht Energie. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/transistor.md b/src/main/resources/assets/opencomputers/doc/de_de/item/transistor.md index 93ca0c966e..636f4b3f98 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/transistor.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/transistor.md @@ -1,5 +1,5 @@ # Transistor -![Ich denke ich habe alle meine Referenzen aufgebraucht.](oredict:oc:materialTransistor) +![Ich denke ich habe alle meine Referenzen aufgebraucht.](oredict:opencomputers:materialTransistor) Der Transistor ist einer der grundlegendsten Crafting-Materialien in OpenComputers. Es wird hauptsächlich für [Microchips](chip1.md) und andere elektronische Kleinigkeiten verwendet. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/upgradecontainer1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/upgradecontainer1.md index 21abefdc7d..58ca6bb859 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/upgradecontainer1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/upgradecontainer1.md @@ -1,5 +1,5 @@ # Upgrade-Container -![Kann Upgrade haben.](oredict:oc:upgradeContainer1) +![Kann Upgrade haben.](oredict:opencomputers:upgradeContainer1) Der Upgrade-Container ist ein Container-Upgrade für [Roboter](../block/robot.md). Es stellt einen Slot im Roboter zur Verfügung, in dem normale Upgrades platziert werden können. Die höchste Stufe das ein Upgrade haben darf gleicht der Stufe des Containers. Im Gegensatz zu normalen Upgrades ist die Komplexität des Containers doppelt so groß wie die Stufe. Für mehr Informationen über Komplexität siehe [Roboter](../block/robot.md) und [Elektronik-Werkbank](../block/assembler.md). diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/wlanCard1.md b/src/main/resources/assets/opencomputers/doc/de_de/item/wlanCard1.md index ca07529a34..4f64ad72d2 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/wlanCard1.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/wlanCard1.md @@ -1,6 +1,6 @@ # Drahtlosnetzwerkkarte -![Kann Krebs verursachen. Oder nicht.](oredict:oc:wlanCard2) +![Kann Krebs verursachen. Oder nicht.](oredict:opencomputers:wlanCard2) Die kabellose Netzwerkkarte ist eine aufgewertete [Netzwerkkarte](lanCard.md) die, zusätzlich zu verkabelten Nachrichten, zudem das Senden von Nachrichten über kabellose Netzwerke ermöglicht. Die Signalstärke kontrolliert die Distanz über die Nachrichten versendet werden können. Die Signalstärke gleicht der Distanz in Blöcken. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/worldsensorcard.md b/src/main/resources/assets/opencomputers/doc/de_de/item/worldsensorcard.md index bf63e2330b..30768e009a 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/worldsensorcard.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/worldsensorcard.md @@ -1,5 +1,5 @@ # Weltsensorkarte -![Um dort hin zu gehen...](oredict:oc:worldSensorCard) +![Um dort hin zu gehen...](oredict:opencomputers:worldSensorCard) Die Weltsensorkarte ermöglicht es Informationen über die Atmosphäre und Gravitation von verschiedenen Planeten in GalactiCraft zu lesen. Das kann für [Roboter](../block/robot.md) oder [Drohnen](drone.md) im Weltraum nützlich sein. diff --git a/src/main/resources/assets/opencomputers/doc/de_de/item/wrench.md b/src/main/resources/assets/opencomputers/doc/de_de/item/wrench.md index 6312b9a64d..6b7e995050 100644 --- a/src/main/resources/assets/opencomputers/doc/de_de/item/wrench.md +++ b/src/main/resources/assets/opencomputers/doc/de_de/item/wrench.md @@ -1,5 +1,5 @@ # Schraubenziehschlüssel -![In der Schweiz gemacht.](oredict:oc:wrench) +![In der Schweiz gemacht.](oredict:opencomputers:wrench) Wie fast jede andere Technologie-Modifikation hat OpenComputer seine eigene Version eines Schraubenschlüssels. In diesem Fall ist es ein Schraubendreher-Schraubenschlüssel-Hybdrid, das unglaublich merkwürdig aussieht. Damit können die meisten Blöcke gedreht werden und ist mit den meisten Mods kompatibel. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/accesspoint.md b/src/main/resources/assets/opencomputers/doc/en_us/block/accesspoint.md index 78bacc26c5..f6e5c1976a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/accesspoint.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/accesspoint.md @@ -1,6 +1,6 @@ # Access Point -![AAA](oredict:oc:accessPoint) +![AAA](oredict:opencomputers:accessPoint) *This block is deprecated and will be removed in a future version.* Craft it into a [relay](relay.md) to avoid losing it. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/adapter.md b/src/main/resources/assets/opencomputers/doc/en_us/block/adapter.md index 4e6bb63710..6e7b6eabbe 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/adapter.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/adapter.md @@ -1,6 +1,6 @@ # Adapter -![Now with 100% more everything.](oredict:oc:adapter) +![Now with 100% more everything.](oredict:opencomputers:adapter) The adapter allows [computers](../general/computer.md) to interact with blocks from vanilla Minecraft or other mods. Supported blocks adjacent to the adapter will show up as components in [computers](../general/computer.md) connected to the adapter. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/assembler.md b/src/main/resources/assets/opencomputers/doc/en_us/block/assembler.md index cb25ceb76e..a6785ac6c0 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/assembler.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/assembler.md @@ -1,6 +1,6 @@ # Assembler -![Harder, better, faster, stronger.](oredict:oc:assembler) +![Harder, better, faster, stronger.](oredict:opencomputers:assembler) The assembler is an advanced workstation that can be used to build more complex electronic devices, such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). They require a large amount of energy to assemble devices, so it is recommended to power them sufficiently with a [capacitor bank](capacitor.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/cable.md b/src/main/resources/assets/opencomputers/doc/en_us/block/cable.md index 8b4c7028ec..8e81a38fb0 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/cable.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/cable.md @@ -1,6 +1,6 @@ # Cable -![Salad.](oredict:oc:cable) +![Salad.](oredict:opencomputers:cable) The cable serves as a way of connecting [computers](../general/computer.md) and machines that are far apart. If you have a compact build where all components touch each other (directly or indirectly, most blocks also behave the same way as cables) you will usually not need cables. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/en_us/block/capacitor.md index 5714f14839..73ddb08746 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/capacitor.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/capacitor.md @@ -1,6 +1,6 @@ # Capacitor -![It's over 9000.](oredict:oc:capacitor) +![It's over 9000.](oredict:opencomputers:capacitor) The capacitor stores energy to be used by the network, acting as an energy buffer when needed. Unlike conversion from other mod's energy to OpenComputers' internal energy type (using a [power converter](powerConverter.md) for example), transferring energy inside a single subnetwork is instantaneous. Having an internal energy buffer will be useful for tasks that require a lot of energy, such as [assembling](assembler.md) and/or [charging](charger.md) devices such as [robots](robot.md) or [drones](../item/drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/case1.md b/src/main/resources/assets/opencomputers/doc/en_us/block/case1.md index aa9c465721..0bbafd7df9 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/case1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/case1.md @@ -1,6 +1,6 @@ # Computer Case -![Just in case.](oredict:oc:case1) +![Just in case.](oredict:opencomputers:case1) Computer cases come in three different tiers, which limits the components that can be inserted into them. An additional tier also exists for use in creative mode only. Computer cases can also be placed inside an [assembler](assembler.md) to build [robots](robot.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/chameliumblock.md b/src/main/resources/assets/opencomputers/doc/en_us/block/chameliumblock.md index 99012ba02c..0521f4124b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/chameliumblock.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/chameliumblock.md @@ -1,6 +1,6 @@ # Block of Chamelium -![So... blank.](oredict:oc:chameliumBlock) +![So... blank.](oredict:opencomputers:chameliumBlock) A few pieces of [chamelium](../item/chamelium.md) can be combined to provide a monochrome block for decorative purposes. Chamelium blocks can also be dyed with any of the 16 Minecraft colors. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/charger.md b/src/main/resources/assets/opencomputers/doc/en_us/block/charger.md index e8d3db1b47..060d089893 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/charger.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/charger.md @@ -1,6 +1,6 @@ # Charger -![All right, let's do this.](oredict:oc:charger) +![All right, let's do this.](oredict:opencomputers:charger) The charger is used to charge devices such as [robots](robot.md), [drones](../item/drone.md) and [tablets](../item/tablet.md). A charger has to be activated by applying a redstone signal to it. The charge speed is based on the applied redstone signal's strength, with a strength of 15 meaning a charge speed of 100%. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/en_us/block/disassembler.md index 770376b9d9..0f5863d38a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/disassembler.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/disassembler.md @@ -1,6 +1,6 @@ # Disassembler -![Build it, tear it down.](oredict:oc:disassembler) +![Build it, tear it down.](oredict:opencomputers:disassembler) The disassembler can be used to deconstruct most items in OpenComputers into their original parts. This is mostly useful to reclaim materials from old parts that are no longer useful, or to deconstruct devices that are either no longer needed or were incorrectly built (e.g. [robots](robot.md) without an [operating system](../general/openOS.md)). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/diskdrive.md b/src/main/resources/assets/opencomputers/doc/en_us/block/diskdrive.md index 5b844adca8..9c5ed502d0 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/diskdrive.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/diskdrive.md @@ -1,6 +1,6 @@ # Disk Drive -![Going round and round and...](oredict:oc:diskDrive) +![Going round and round and...](oredict:opencomputers:diskDrive) The disk drive can be used to read [floppy disks](../item/floppy.md) using a [computer](../general/computer.md) connected to the disk drive. This is useful to get started, since the lower tier [computer cases](case1.md) do not have a built-in floppy slot, and you'll need an operating system to boot up the [computer](../general/computer.md). An [OpenOS](../general/openOS.md) disk can be crafted using an empty [floppy disk](../item/floppy.md) and a [manual](../item/manual.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/en_us/block/geolyzer.md index e7c190a69f..b8c409caa1 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/geolyzer.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/geolyzer.md @@ -1,6 +1,6 @@ # Geolyzer -![It rocks.](oredict:oc:geolyzer) +![It rocks.](oredict:opencomputers:geolyzer) The geolyzer can be used by [computers](../general/computer.md) to scan the terrain surrounding the geolyzer for the blocks' approximate hardness. This can be useful to generate maps of the area to display on [hologram projectors](hologram1.md) as well as to detect potentially valuable blocks (ores are usually harder than dirt and stone). Geolyzer scan results have a certain amount of noise added; in theory, multiple scans can be performed to determine a more accurate reading of a block's hardness level. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/en_us/block/hologram1.md index 0e6d897692..8191ff017f 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/hologram1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/hologram1.md @@ -1,6 +1,6 @@ # Hologram Projector -![Is this the real life? Is this just fantasy?](oredict:oc:hologram1) +![Is this the real life? Is this just fantasy?](oredict:opencomputers:hologram1) The hologram projector is a volumetric display, i.e. it provides a three dimensional array of voxels that can be individually enabled or disabled by a connected [computer](../general/computer.md). The second tier projector, while having the same resolution as the tier 1 projector, supports displaying the individual voxels in three different user-definable colors. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/en_us/block/keyboard.md index 485cc6942f..20327f920a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/keyboard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/keyboard.md @@ -1,6 +1,6 @@ # Keyboard -![QWERTY](oredict:oc:keyboard) +![QWERTY](oredict:opencomputers:keyboard) A keyboard is needed to type text on [screens](screen1.md), be they in the world or built into devices such as [robots](robot.md) or [tablets](../item/tablet.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/motionsensor.md b/src/main/resources/assets/opencomputers/doc/en_us/block/motionsensor.md index 37225ec63e..5f6e78a218 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/motionsensor.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/motionsensor.md @@ -1,6 +1,6 @@ # Motion Sensor -![Don't. Blink.](oredict:oc:motionSensor) +![Don't. Blink.](oredict:opencomputers:motionSensor) The motion sensor allows [computers](../general/computer.md) to detect movement of living entities. If an entity moves faster than a set threshold, a signal will be injected into [computers](../general/computer.md) connected to the motion sensor. The threshold can be configured using the component API that the motion sensor exposes to connected computers. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/netsplitter.md b/src/main/resources/assets/opencomputers/doc/en_us/block/netsplitter.md index f6c02a7526..9122b71c45 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/netsplitter.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/netsplitter.md @@ -1,6 +1,6 @@ # Net Splitter -![*.net *.split](oredict:oc:netSplitter) +![*.net *.split](oredict:opencomputers:netSplitter) The net splitter is a device that allows controlling connectivity between subnetworks. Unlike the [relay](relay.md) or [power converter](powerConverter.md) it directly connects adjacent subnetworks, i.e. components can be accessed. Each side's connectivity can be toggled using a wrench (e.g. the [scrench](../item/wrench.md)). When a redstone signal is applied to the net splitter, all sides' connectivity is inverted. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/powerconverter.md b/src/main/resources/assets/opencomputers/doc/en_us/block/powerconverter.md index 07728c8922..735937e8af 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/powerconverter.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/powerconverter.md @@ -1,5 +1,5 @@ # Power Converter -![One of us? One of us!](oredict:oc:powerConverter) +![One of us? One of us!](oredict:opencomputers:powerConverter) The power converter serves as the fastest way to convert energy from other mods' power systems to OpenComputers' internal energy. If you only run a simple computer, you probably won't need a converter. If you have a large capacitor bank that you only drain every now and then, you probably won't need one, either. However, if you wish to directly power an [assembler](assembler.md) or [charger](charger.md), it is usually a good idea to use a converter instead of directly connecting them to external power. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/powerdistributor.md b/src/main/resources/assets/opencomputers/doc/en_us/block/powerdistributor.md index 70ec54adf4..13a4586fc4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/powerdistributor.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/powerdistributor.md @@ -1,5 +1,5 @@ # Power Distributor -![Power to the masses.](oredict:oc:powerDistributor) +![Power to the masses.](oredict:opencomputers:powerDistributor) The power distributor distributes a shared power storage (such as a [capacitor](capacitor.md)), allowing several subnetworks to share their energy without components being exposed to computers in other networks. It operates by regularly "balancing" the energy in all subnetworks it is connected to, so that the *relative* amount of energy is the same in them. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/printer.md b/src/main/resources/assets/opencomputers/doc/en_us/block/printer.md index 3fdb09cae1..7e856fee6b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/printer.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/printer.md @@ -1,6 +1,6 @@ # 3D Printer -![2D printing is so yesteryear.](oredict:oc:printer) +![2D printing is so yesteryear.](oredict:opencomputers:printer) 3D printers allow you to print any block of any shape, with any type of texture. To get started with 3D printers, you will need to place down a 3D printer block next to a computer. This will give access to the `printer3d` component API, allowing you to set up and print [models](print.md) using the provided functions. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/rack.md b/src/main/resources/assets/opencomputers/doc/en_us/block/rack.md index 528344aba7..5c2c308f9a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/rack.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/rack.md @@ -1,6 +1,6 @@ # Rack -![Free housing.](oredict:oc:rack) +![Free housing.](oredict:opencomputers:rack) A rack houses up to four rack mountables such as [servers](../item/server1.md), [terminal servers](../item/terminalServer.md) and [mountable disk drives](../item/diskDriveMountable.md). Connectivity of mountables in a rack can be configured in detail via the GUI. In particular, if [servers](../item/server1.md) contain components that support it, such as [network cards](../item/lanCard.md), network-only connections can be defined for those components. These connections will serve purely for passing along network messages, components will not be visible through them. Such network-only connections are differentiated by the lines being slimmer than the "main" connections, which also allow component access. Each internal connection must be between a mountable / component in a mountable and a bus connected to a side of the rack. To connect multiple mountables to each other, connect them to the same bus. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/raid.md b/src/main/resources/assets/opencomputers/doc/en_us/block/raid.md index 87eda27777..3ccb0efe3b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/raid.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/raid.md @@ -1,6 +1,6 @@ # Raid -![40 man instance.](oredict:oc:raid) +![40 man instance.](oredict:opencomputers:raid) The raid block houses three [hard drives](../item/hdd1.md) which will be combined into a single file system. This combined file system has the size of the sum of the capacities of the individual [hard drives](../item/hdd1.md) and is available to all [computers](../general/computer.md) connected to the raid. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/redstone.md b/src/main/resources/assets/opencomputers/doc/en_us/block/redstone.md index 8978fc8842..df2b737c92 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/redstone.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/redstone.md @@ -1,6 +1,6 @@ # Redstone I/O -![Hi Red.](oredict:oc:redstone) +![Hi Red.](oredict:opencomputers:redstone) The redstone I/O block can be used to remotely read and emit redstone signals. It behaves like a hybrid of a tier 1 and 2 [redstone card](../item/redstoneCard1.md): it can read and emit simple analog as well as bundled signals, but cannot read or emit wireless redstone signals. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/relay.md b/src/main/resources/assets/opencomputers/doc/en_us/block/relay.md index 94fc589c28..ac8b585185 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/relay.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/relay.md @@ -1,6 +1,6 @@ # Relay -![Building bridges.](oredict:oc:relay) +![Building bridges.](oredict:opencomputers:relay) The relay can be used to allow different subnetworks to send network messages to each other, without exposing components to [computers](../general/computer.md) in other networks. Keeping components local is usually a good idea, to avoid [computers](../general/computer.md) using the wrong [screen](screen1.md) or to avoid component overflows to happen (causing [computers](../general/computer.md) to crash and refuse to boot up). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/screen1.md b/src/main/resources/assets/opencomputers/doc/en_us/block/screen1.md index 75710fb6b1..8781f5d52a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/screen1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/screen1.md @@ -1,6 +1,6 @@ # Screens -![See this?](oredict:oc:screen1) +![See this?](oredict:opencomputers:screen1) A screen is used in combination with a [graphics card](../item/graphicsCard1.md), to allow [computers](../general/computer.md) to display text. Different screen tiers have different capabilities, such as supporting different resolutions and color depths. Screens range from low-resolution, monochrome displays to high-resolution displays with up to 256 colors. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/switch.md b/src/main/resources/assets/opencomputers/doc/en_us/block/switch.md index cff609e1c3..08164952e3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/switch.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/switch.md @@ -1,6 +1,6 @@ # Switch -![Building bridges.](oredict:oc:switch) +![Building bridges.](oredict:opencomputers:switch) *This block is deprecated and will be removed in a future version.* Craft it into a [relay](relay.md) to avoid losing it. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/transposer.md b/src/main/resources/assets/opencomputers/doc/en_us/block/transposer.md index f666883bbe..840dfe7383 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/transposer.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/transposer.md @@ -1,6 +1,6 @@ # Transposer -![Such a poser.](oredict:oc:transposer) +![Such a poser.](oredict:opencomputers:transposer) The transposer bridges the gap between redstone controlled hoppers and [robots](robot.md), allowing [computer](../general/computer.md)-controlled transferral of items and fluids between adjacent blocks. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/block/waypoint.md b/src/main/resources/assets/opencomputers/doc/en_us/block/waypoint.md index 00dab81a44..bb6893ea1d 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/block/waypoint.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/block/waypoint.md @@ -1,6 +1,6 @@ # Waypoint -!["This way!" - "No, that way!"](oredict:oc:waypoint) +!["This way!" - "No, that way!"](oredict:opencomputers:waypoint) The waypoint's use lies not in itself, but in how it can be used. [Navigation upgrades](../item/navigationUpgrade.md) can detect waypoints, so devices with a navigation upgrade can use these waypoints to navigate the world. This is particularly useful for writing easily reusable programs for devices such as [robots](robot.md) and [drones](../item/drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/general/example.md b/src/main/resources/assets/opencomputers/doc/en_us/general/example.md index 3bdda70bc6..8db963f6c1 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/general/example.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/general/example.md @@ -4,13 +4,13 @@ This is some test text for the subset of Markdown supported by the planned ingam ![This is a tooltip...](opencomputers:textures/gui/printer_ink.png) ![This is a tooltip...](opencomputers:/textures/gui/printer_material.png) *This* is *italic* text, ~~strikethrough~~ maybe abc-ter **some** text **in bold**. Is _this underlined_? Oh, no, _it's also italic!_ Well, this [a link](../index.md). -![This is rendered live.](oredict:oc:assembler) +![This is rendered live.](oredict:opencomputers:assembler) ## Smaller headline [also with *link* but this __one__ longer](../block/adapter.md) -![This is another tooltip.](item:OpenComputers:item@23) +![This is another tooltip.](item:opencomputers:transistor) some text directly above the item stack renderer to test spacing -![All the colors.](oredict:craftingPiston) +![All the colors.](oredict:forge/piston) some text directly below the item stack renderer to test spacing This is *italic @@ -42,9 +42,9 @@ asdasd ![oh my god, the recursion!](img/example.png) qweqwe And finally, [this is a link!](https://avatars1.githubusercontent.com/u/514903). -![broken item image](item:this is broken) -![broken item image](block:this is broken) -![broken item image](oredict:this is broken) +![broken item image](item:this_is_broken) +![broken item image](block:this_is_broken) +![broken item image](oredict:this_is_broken) wrap testing 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 @@ -53,17 +53,17 @@ wrap testing * 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 - `123456789012345678901234567890.12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890` -this is a test for an![](oredict:oc:cpu1)an inline image kakakakalalsd 123 as +this is a test for an![](oredict:opencomputers:cpu1)an inline image kakakakalalsd 123 as -this is a test for an![](oredict:oc:cpu1) +this is a test for an![](oredict:opencomputers:cpu1) an image with a break after it this is a test for an -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) an image between two lines this is a test for an -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) an image between two blank lines diff --git a/src/main/resources/assets/opencomputers/doc/en_us/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/en_us/general/quickstart.md index fe5d776758..42c6038ec1 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/general/quickstart.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/general/quickstart.md @@ -6,7 +6,7 @@ Also know as "how to build your first computer". To get your first [computer](co First off, you will need a [computer case](../block/case1.md). This is the block which will contain all of the components, defining the behavior of the computer you are building. -![A tier two computer case.](oredict:oc:case2) +![A tier two computer case.](oredict:opencomputers:case2) For example, you will need to choose what tier of [graphics card](../item/graphicsCard1.md) you wish to use, if you need a [network card](../item/lanCard.md), a [redstone card](../item/redstoneCard1.md) or, if you're just playing around in creative mode, maybe even a [debug card](../item/debugCard.md). @@ -37,7 +37,7 @@ Now, if you used a tier 2 [computer case](../block/case2.md) as in the screensho It lives! Or should, anyway. If it doesn't something went wrong, and you'll want to investigate using the [analyzer](../item/analyzer.md). But assuming it's running now, you're pretty much done. The hardest part is over. All that's left is to make it take input and show some output. To allow the [computer](computer.md) to show some output, you'll want to grab a [screen](../block/screen1.md) and a [graphics card](../item/graphicsCard1.md). -![No, it's not a flatscreen.](oredict:oc:screen2) +![No, it's not a flatscreen.](oredict:opencomputers:screen2) Place the [screen](../block/screen1.md) adjacent to your [computer case](../block/case1.md), or, again, connect it using some [cable](../block/cable.md). Then place a [graphics card](../item/graphicsCard1.md) of your choice into the [computer case](../block/case1.md). You should now see a blinking cursor on the [screen](../block/screen1.md). Finally, place a [keyboard](../block/keyboard.md) either on the [screen](../block/screen1.md) itself, or in a way so that it faces the [screen](../block/screen1.md), to enable [keyboard](../block/keyboard.md) input. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/abstractbuscard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/abstractbuscard.md index 4263adfe2d..081e0788f0 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/abstractbuscard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/abstractbuscard.md @@ -1,5 +1,5 @@ # Abstract Bus Card -![More networking!](oredict:oc:abstractBusCard) +![More networking!](oredict:opencomputers:abstractBusCard) This card allows [computers](../general/computer.md), [servers](server1.md) and [robots](../block/robot.md) to interact with StargateTech2's abstract bus. When the card is installed, these blocks will connect to the abstract bus and a component becomes available to the machine that can be used to send messages across the abstract bus. Incoming abstract bus messages are converted to signals that are injected into the machine. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/acid.md b/src/main/resources/assets/opencomputers/doc/en_us/item/acid.md index a8020c0da1..d7d8ef0ba5 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/acid.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/acid.md @@ -1,6 +1,6 @@ # Acid -![Reflux?](oredict:oc:materialAcid) +![Reflux?](oredict:opencomputers:materialAcid) This tasty [citation needed] concoction can be consumed if you ever feel the need for some... fun. Or ruining your digestive tract. Or both. It can also serve as ingredient in other, more useful items. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/alu.md b/src/main/resources/assets/opencomputers/doc/en_us/item/alu.md index d429cb4045..3625a3e602 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/alu.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/alu.md @@ -1,5 +1,5 @@ # Arithmetic Logic Unit -![I can into logic!](oredict:oc:materialALU) +![I can into logic!](oredict:opencomputers:materialALU) Used for crafting components that perform calculations, such as [CPUs](cpu1.md) and [graphics cards](graphicsCard1.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/en_us/item/analyzer.md index b185704af1..92f8e0ee30 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/analyzer.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/analyzer.md @@ -1,6 +1,6 @@ # Analyzer -![Must. Resist. Bad. Joke.](oredict:oc:analyzer) +![Must. Resist. Bad. Joke.](oredict:opencomputers:analyzer) The analyzer is a handy tool for reading information about OpenComputers-related blocks in the world. Simply (sneak-)activate a block to get some information printed to the chat box. This ranges from basic things like the address of components, to power levels in the subnetwork the block is in, and information on the error lead to a [computer](../general/computer.md) to crash, for example. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/angelupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/angelupgrade.md index 611146a39c..badae522c2 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/angelupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/angelupgrade.md @@ -1,5 +1,5 @@ # Angel Upgrade -![Hallelujah.](oredict:oc:angelUpgrade) +![Hallelujah.](oredict:opencomputers:angelUpgrade) This upgrade allows [robots](../block/robot.md) to place blocks in thin air, without a reference block. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/apu1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/apu1.md index 674851e7af..872e4a46ca 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/apu1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/apu1.md @@ -1,6 +1,6 @@ # APU -![Awesomest Probability Unifier.](oredict:oc:apu1) +![Awesomest Probability Unifier.](oredict:opencomputers:apu1) These parts are the merry marriage of a [CPU](cpu1.md) and [graphics card](graphicsCard1.md). Using one of these essentially gives you one more card slot to work with. Like a normal CPU, it defines the architecture of the [computer](../general/computer.md), and the number of components that can be connected to the [computer](../general/computer.md) before it stops working. In addition it also provides basic graphical capabilities. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/arrowkeys.md b/src/main/resources/assets/opencomputers/doc/en_us/item/arrowkeys.md index 8357b596c5..9d46464710 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/arrowkeys.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/arrowkeys.md @@ -1,5 +1,5 @@ # Arrow Keys -![Just be grateful it's not made from arrows.](oredict:oc:materialArrowKey) +![Just be grateful it's not made from arrows.](oredict:opencomputers:materialArrowKey) At the risk of repeating myself: it's a button sink. Because the button economy has seen some serious inflation in recent years. It is used as a component for building [keyboards](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/batteryupgrade1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/batteryupgrade1.md index d1c06b34c5..c7ea13cd9b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/batteryupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/batteryupgrade1.md @@ -1,5 +1,5 @@ # Battery Ugrade -![Made of Metal.](oredict:oc:batteryUpgrade1) +![Made of Metal.](oredict:opencomputers:batteryUpgrade1) This upgrade increases the internal energy buffer of devices, such as [robots](../block/robot.md) and [tablets](tablet.md), allowing them to operate longer without having to return to a [charger](../block/charger.md). Higher tier battery upgrades can store more energy. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/buttongroup.md b/src/main/resources/assets/opencomputers/doc/en_us/item/buttongroup.md index 373d7cdc3b..1080f7f8fa 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/buttongroup.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/buttongroup.md @@ -1,5 +1,5 @@ # Button Group -![Needs more buttons.](oredict:oc:materialButtonGroup) +![Needs more buttons.](oredict:opencomputers:materialButtonGroup) Because you *always* have too many buttons lying around somewhere. Don't lie. We all shift-click that button recipe time and again. Button groups are used to build [keyboards](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/card.md b/src/main/resources/assets/opencomputers/doc/en_us/item/card.md index 55c5021b7a..d8479bcd9d 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/card.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/card.md @@ -1,5 +1,5 @@ # Card -![Can't be read.](oredict:oc:materialCard) +![Can't be read.](oredict:opencomputers:materialCard) Common crafting material for card components in OpenComputers (such as [graphics cards](graphicsCard1.md), [network cards](lanCard.md), etc). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/cardcontainer1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/cardcontainer1.md index 64698c7df8..519e17b88e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/cardcontainer1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/cardcontainer1.md @@ -1,5 +1,5 @@ # Card Container -![Can haz cards!](oredict:oc:cardContainer1) +![Can haz cards!](oredict:opencomputers:cardContainer1) The card container is a container upgrade for [robots](../block/robot.md) allowing cards to be inserted/removed to/from [robots](../block/robot.md) on-the-fly. The maximum tier of card that the slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. See [here](../block/robot.md) for details on robot complexity. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/chamelium.md b/src/main/resources/assets/opencomputers/doc/en_us/item/chamelium.md index 18fabca864..7c2eb60c68 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/chamelium.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/chamelium.md @@ -1,6 +1,6 @@ # Chamelium -![From Chameleon, in case you were wondering.](oredict:oc:chamelium) +![From Chameleon, in case you were wondering.](oredict:opencomputers:chamelium) Chamelium is a shape-shifting material that is used when creating [3D prints](../block/print.md) in a [3D printer](../block/printer.md). On its own, it is featureless and therefore very useful for creating simple, plain and monochrome areas. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/chip1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/chip1.md index 945b9a8d82..bb4d72cdf4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/chip1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/chip1.md @@ -1,5 +1,5 @@ # Microchips -![Not the edible ones.](oredict:oc:circuitChip1) +![Not the edible ones.](oredict:opencomputers:circuitChip1) Microchips are the bread and butter of electronic component crafting. They come in different tiers, for crafting different tiers of components. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/chunkloaderupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/chunkloaderupgrade.md index 7f7e8210bc..dbbafe00c6 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/chunkloaderupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/chunkloaderupgrade.md @@ -1,6 +1,6 @@ # Chunk Loader Upgrade -![Not going anywhere.](oredict:oc:chunkloaderUpgrade) +![Not going anywhere.](oredict:opencomputers:chunkloaderUpgrade) The chunk loader upgrade can be installed in devices (such as [robots](../block/robot.md) and [microcontrollers](../block/microcontroller.md)) to allow them to keep the chunk they are in - as well as the surrounding chunks - loaded. This consumes energy, however. The chunk loader can be turned on and off using the component API exposed to the device. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/circuitboard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/circuitboard.md index 28ad8ecf7f..e2f0493d60 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/circuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/circuitboard.md @@ -1,5 +1,5 @@ # Circuit Board -![Needs more gold.](oredict:oc:materialCircuitBoard) +![Needs more gold.](oredict:opencomputers:materialCircuitBoard) Intermediate crafting item made from [raw circuit boards](rawCircuitBoard.md) and used to make [printed circuit boards](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/componentbus1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/componentbus1.md index b6d2990e30..622cf9079e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/componentbus1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/componentbus1.md @@ -1,6 +1,6 @@ # Component Bus -![I need mooooore.](oredict:oc:componentBus1) +![I need mooooore.](oredict:opencomputers:componentBus1) A component bus is a [server](server1.md)-specific upgrade that allows the [server](server1.md) to communicate with more components at the same time, without shutting down. Like with [CPUs](cpu1.md), higher tier buses provide higher component limits. Higher tier [servers](server1.md) are also capable of taking more component buses, allowing for communication with many more components. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/controlunit.md b/src/main/resources/assets/opencomputers/doc/en_us/item/controlunit.md index 8935aeb967..493a6eeee3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/controlunit.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/controlunit.md @@ -1,5 +1,5 @@ # Control Unit -![With built-in cruise control.](oredict:oc:materialCU) +![With built-in cruise control.](oredict:opencomputers:materialCU) Higher tier crafting item used in more advanced circuitry, such as [CPUs](cpu1.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/cpu1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/cpu1.md index 7ff2673948..4fc4547181 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/cpu1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/cpu1.md @@ -1,6 +1,6 @@ # CPU -![Braaainz.](oredict:oc:cpu1) +![Braaainz.](oredict:opencomputers:cpu1) The central processing unit is a core part for each [computer](../general/computer.md) or [server](server1.md). It defines the architecture of the [computer](../general/computer.md), and the number of components that can be connected to the [computer](../general/computer.md) before it stops working. Higher tier CPUs also provide a higher per-tick direct call limit to the [computer](../general/computer.md) - in simpler terms: better CPUs run faster. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/craftingupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/craftingupgrade.md index 43320ee5ea..2d726ab3f4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/craftingupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/craftingupgrade.md @@ -1,5 +1,5 @@ # Crafting Upgrade -![Crafty.](oredict:oc:craftingUpgrade) +![Crafty.](oredict:opencomputers:craftingUpgrade) The crafting upgrade allows [robots](../block/robot.md) to craft shaped and shapeless recipes using items in their [inventory](../item/inventoryUpgrade.md). When crafting, the top-left 3x3 grid in the [robot](../block/robot.md)'s [inventory](../item/inventoryUpgrade.md) is used as the crafting grid. Items have to be arranged according to the recipe. Results will be placed back into the [robot](../block/robot.md)'s [inventory](../item/inventoryUpgrade.md). As with picking up items, the result will be placed into the selected slot; failing to do so will place the item in the next available empty slot. If no inventory space remains, the result will be dropped into the world. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/cuttingwire.md b/src/main/resources/assets/opencomputers/doc/en_us/item/cuttingwire.md index 8f532bc68e..12942c96e5 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/cuttingwire.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/cuttingwire.md @@ -1,5 +1,5 @@ # Cutting Wire -![Not a garrote. Honest.](oredict:oc:materialCuttingWire) +![Not a garrote. Honest.](oredict:opencomputers:materialCuttingWire) An item encountered when using hard-mode recipes, it is used for crafting [raw circuit boards](rawCircuitBoard.md). Very inefficiently. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/databaseupgrade1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/databaseupgrade1.md index ff4b4cfd5c..b1b1d7228c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/databaseupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/databaseupgrade1.md @@ -1,6 +1,6 @@ # Database Upgrade -![Living in the database.](oredict:oc:databaseUpgrade1) +![Living in the database.](oredict:opencomputers:databaseUpgrade1) The database upgrade can be configured to store a list of item stack representations, which can then be used by other components. This is particularly useful for items that are differentiated purely based on their NBT data, which is not part of the item stack descriptor returned by callbacks. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/datacard1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/datacard1.md index de4e1798bd..6888647813 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/datacard1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/datacard1.md @@ -1,6 +1,6 @@ # Data Card -![Contrary to popular belief, it does not store data.](oredict:oc:dataCard1) +![Contrary to popular belief, it does not store data.](oredict:opencomputers:dataCard1) The data card is a utility card that provides a couple of algorithms which would be either hard to implement on an architecture, or run relatively slowly on them. It provides hashing functionalities, as well as basic inflate/deflate. Additionally it comes with an embedded file system that provides a number of programs using the functionality provided by the card, similar to the internet card. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/debugcard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/debugcard.md index aa35df5a79..ee40ba57b1 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/debugcard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/debugcard.md @@ -1,6 +1,6 @@ # Debug Card -![Wait, if I- oooooh.](item:OpenComputers:item@73) +![Wait, if I- oooooh.](item:opencomputers:debugcard) The debug card is a creative-only item that was originally only intended to make debugging things easier, by automating some processes. It has since gotten a bunch more functionality, making it quite useful for custom map-making. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/disk.md b/src/main/resources/assets/opencomputers/doc/en_us/item/disk.md index 55a6e9c13d..c99793fc9b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/disk.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/disk.md @@ -1,5 +1,5 @@ # Disc -![World. RIP Terry Pratchett.](oredict:oc:materialDisk) +![World. RIP Terry Pratchett.](oredict:opencomputers:materialDisk) Basic crafting component used in crafting storage media such as [floppies](floppy.md) and [hard drives](hdd1.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/diskdrivemountable.md b/src/main/resources/assets/opencomputers/doc/en_us/item/diskdrivemountable.md index eecb3e7c5f..d5cf0f3165 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/diskdrivemountable.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/diskdrivemountable.md @@ -1,5 +1,5 @@ # Mountable Disk Drive -![Snuggly](oredict:oc:diskDriveMountable) +![Snuggly](oredict:opencomputers:diskDriveMountable) This device is functionally equivalent to a regular [disk drive](../block/diskDrive.md), except that it is installed in a [rack](../block/rack.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/drone.md b/src/main/resources/assets/opencomputers/doc/en_us/item/drone.md index e639c1982a..981f6cbd35 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/drone.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/drone.md @@ -1,5 +1,5 @@ # Drone -![Big brother is trying to watch you.](item:OpenComputers:item@84) +![Big brother is trying to watch you.](item:opencomputers:drone) Drones are built using a [drone case](droneCase1.md) in the [assembler](../block/assembler.md). They are entity-based [robots](../block/robot.md), a little cheaper with limited functionality. They are also capable of moving differently and much quicker than [robots](../block/robot.md), and are usually controlled using a client program on a [computer](../general/computer.md). The drone will need a configured [EEPROM](eeprom.md) to listen for commands to be executed or act on its own. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/dronecase1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/dronecase1.md index 3cb50e9f7f..661e889059 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/dronecase1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/dronecase1.md @@ -1,6 +1,6 @@ # Drone Case -![Droning on.](oredict:oc:droneCase1) +![Droning on.](oredict:opencomputers:droneCase1) The drone case is used to build [drones](drone.md) in the [assembler](../block/assembler.md). [Drones](drone.md) are light-weight, fast and very mobile machines with limited functionality (fewer upgrade and component slots available). Unlike [robots](../block/robot.md) they cannot use tools, and can interact with the world only in a relatively limited manner. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/eeprom.md b/src/main/resources/assets/opencomputers/doc/en_us/item/eeprom.md index e4019afbbf..583dbdafd7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/eeprom.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/eeprom.md @@ -1,6 +1,6 @@ # EEPROM -![Let's get this party started.](oredict:oc:eeprom) +![Let's get this party started.](oredict:opencomputers:eeprom) The EEPROM is what contains the code used to initialize a computer when it is being booted. This data is stored as a plain byte array, and may mean different things to different [CPU](cpu1.md) architectures. For example, for Lua it is usually a small script that searches for file systems with an init script, for other architectures it may be actual machine code. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/experienceupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/experienceupgrade.md index 5112fee915..6b9082770e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/experienceupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/experienceupgrade.md @@ -1,6 +1,6 @@ # Experience Upgrade -![This makes no sense, but it's cool.](oredict:oc:experienceUpgrade) +![This makes no sense, but it's cool.](oredict:opencomputers:experienceUpgrade) The experience upgrade is a very special upgrade, as it allows [robots](../block/robot.md) and [drones](drone.md) to collect experience by performing various actions, such as digging up ores and killing entities. A single upgrade can store up to 30 levels, providing passive bonuses with each level, including faster harvest speeds and increased energy buffer capacity. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/floppy.md b/src/main/resources/assets/opencomputers/doc/en_us/item/floppy.md index ae60719558..d41d980e63 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/floppy.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/floppy.md @@ -1,5 +1,5 @@ # Floppy Disk -![Many inches.](oredict:oc:floppy) +![Many inches.](oredict:opencomputers:floppy) The floppy disk is the cheapest and smallest type of storage medium in OpenComputers. It is a handy early-game way of storing data and transferring it between [computers](../general/computer.md) and [robots](../block/robot.md). You may also find floppy disks with useful programs on them in dungeon chests (OpenPrograms Package Manager is a good example, allowing easy install of programs from a central GitHub repository). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/generatorupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/generatorupgrade.md index 27c5dca641..0d402d8a8e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/generatorupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/generatorupgrade.md @@ -1,6 +1,6 @@ # Generator Upgrade -![Generator X.](oredict:oc:generatorUpgrade) +![Generator X.](oredict:opencomputers:generatorUpgrade) The generator upgrade allows devices to re-fuel on the go. Currently it only supports solid fuels, such as coal. It has an internal inventory that can store one item stack of fuel. Surplus fuel can be removed from the generator using the appropriate component API method. When removing a generator upgrade from a [robot](../block/robot.md), its contents will be dropped into the world. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/graphicscard1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/graphicscard1.md index e72fc5c6c0..b9174280a3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/graphicscard1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/graphicscard1.md @@ -1,6 +1,6 @@ # Graphics Card -![Fancy images.](oredict:oc:graphicsCard1) +![Fancy images.](oredict:opencomputers:graphicsCard1) The graphics card is an essential part for most [computers](../general/computer.md) and allows the [computer](../general/computer.md) to display text on a connected [screen](../block/screen1.md). Graphics cards come in several tiers, and like [screens](../block/screen1.md), support different resolutions and color depths. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/hdd1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/hdd1.md index c873304a48..3693e08691 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/hdd1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/hdd1.md @@ -1,5 +1,5 @@ # Hard Disk Drive -![Spaaaace.](oredict:oc:hdd1) +![Spaaaace.](oredict:opencomputers:hdd1) The hard disk drives are a higher tier storage medium in OpenComputers. All storage media perform at the same speed; higher tier storage provides more space. There are also some devices that can only use disk drives (although servers could use an external [disk drive](../block/diskDrive.md), for example). Hard drives can be placed inside a [raid](../block/raid.md), allowing multiple drives to share the same file system. Note that placing a hard drive in a [raid](../block/raid.md) wipes the drive of its contents. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/hoverboots.md b/src/main/resources/assets/opencomputers/doc/en_us/item/hoverboots.md index 8ff8a375d5..ff600be336 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/hoverboots.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/hoverboots.md @@ -1,6 +1,6 @@ # Hover Boots -![Step on it.](oredict:oc:hoverBoots) +![Step on it.](oredict:opencomputers:hoverBoots) If you can't be bothered to program [drones](drone.md), here's an alternative use for them: stepping stones! Or glorified inline skates. Something like that. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/hoverupgrade1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/hoverupgrade1.md index 5406e23dda..a5a9bfdb82 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/hoverupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/hoverupgrade1.md @@ -1,6 +1,6 @@ # Hover Upgrade -![Float like a feather.](oredict:oc:hoverUpgrade1) +![Float like a feather.](oredict:opencomputers:hoverUpgrade1) The hover upgrade allows [robots](../block/robot.md) to fly much higher above the ground than they normally could. Unlike [drones](drone.md), they are by default limited to a flight height of 8. This is usually not a big problem, because they can still move up or along walls. Their general movement rules can be summarized like this: - Robots may only move if the start or target position is valid (e.g. to allow building bridges). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/inkcartridge.md b/src/main/resources/assets/opencomputers/doc/en_us/item/inkcartridge.md index 14ae30e03c..574e3db117 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/inkcartridge.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/inkcartridge.md @@ -1,5 +1,5 @@ # Ink Cartridge -![The colors of the rainbow.](oredict:oc:inkCartridge) +![The colors of the rainbow.](oredict:opencomputers:inkCartridge) Ink cartridges come in handy when refilling the color buffer of [3D printers](../block/printer.md). While it is also possible to refill them using dyes directly, this is messy and very inefficient. It is strongly recommended to invest into a real OC Ink Cartridge (TM), today! (Disclaimer: they may or may cost more than the printer itself). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/internetcard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/internetcard.md index fa80e6d7f9..33190a8a40 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/internetcard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/internetcard.md @@ -1,6 +1,6 @@ # Internet Card -![Cat videos in 3, 2, ...](oredict:oc:internetCard) +![Cat videos in 3, 2, ...](oredict:opencomputers:internetCard) The internet card grants [computers](../general/computer.md) access to the internet. It provides ways to perform simple HTTP requests, as well as to open plain TCP client sockets that can be read and written to. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/interweb.md b/src/main/resources/assets/opencomputers/doc/en_us/item/interweb.md index 91520ca79b..8d482a060f 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/interweb.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/interweb.md @@ -1,5 +1,5 @@ # Interweb -![A website is a place where there's cobweb.](oredict:oc:materialInterweb) +![A website is a place where there's cobweb.](oredict:opencomputers:materialInterweb) The interweb is a basic component for all things related to long distance communication. It uses the strange mechanics of all things End to allow something along the lines of quantum communication. Used most notably in [internet cards](internetCard.md) and [linked cards](linkedCard.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/inventorycontrollerupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/inventorycontrollerupgrade.md index 8cad6000e1..8cddea326d 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/inventorycontrollerupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/inventorycontrollerupgrade.md @@ -1,6 +1,6 @@ # Inventory Controller -![I'm in control.](oredict:oc:inventoryControllerUpgrade) +![I'm in control.](oredict:opencomputers:inventoryControllerUpgrade) The inventory controller upgrade provides extended inventory interaction to [robots](../block/robot.md) and [drones](drone.md). It allows the device to explicitly target slots in external inventories when dropping or sucking items. It also allows devices to read detailed information about item stacks. Lastly it provides [robots](../block/robot.md) with a means to change their equipped tool without external help. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/inventoryupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/inventoryupgrade.md index a451f184c7..a7d18f7dd8 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/inventoryupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/inventoryupgrade.md @@ -1,6 +1,6 @@ # Inventory Upgrade -![Where does it keep all this stuff...](oredict:oc:inventoryUpgrade) +![Where does it keep all this stuff...](oredict:opencomputers:inventoryUpgrade) The inventory upgrade provides inventory slots to [robots](../block/robot.md) and [drones](drone.md). For each inventory upgrade a [robot](../block/robot.md) will gain an addition 16 inventory slots, up to a maximum of 64 slots in total; a [drone](drone.md) will gain 4 slots per upgrade, up to a total of 8 slots. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/lancard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/lancard.md index fc730e0359..d14fa8039e 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/lancard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/lancard.md @@ -1,5 +1,5 @@ # Network Card -![Enter the network.](oredict:oc:lanCard) +![Enter the network.](oredict:opencomputers:lanCard) The network card allows [computers](../general/computer.md) to send and receive network messages. Messages (or packets) can be broadcasted to all receiving nodes in a subnetwork, or sent to a specific node with a specified address. [Relays](../block/relay.md) can be used to bridge multiple subnetworks by relaying messages between the subnetworks they are connected to. It is also possible to send a targeted message if the receiver is in another subnetwork, if the networks are connected via one or more [relays](../block/relay.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/leashupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/leashupgrade.md index 0f2914abc6..8f745a7cbe 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/leashupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/leashupgrade.md @@ -1,5 +1,5 @@ # Leash Upgrade -![-redacted- ~ Vexatos 2015](oredict:oc:leashUpgrade) +![-redacted- ~ Vexatos 2015](oredict:opencomputers:leashUpgrade) The Leash upgrade allows putting animals on a leash, bound to the entity that hosts the device the component is used by, for example [drones](drone.md). Using this upgrade, multiple animals can be leashed at the same time, which makes this quite useful for moving herds. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/linkedcard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/linkedcard.md index ec3dc820c7..1ea92aab6c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/linkedcard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/linkedcard.md @@ -1,5 +1,5 @@ # Linked Card -![I feel we some kind of connection.](oredict:oc:linkedCard) +![I feel we some kind of connection.](oredict:opencomputers:linkedCard) The linked card is a specialized but advanced version of a [network card](lanCard.md). It can only operate in pairs, providing a point-to-point communication between the paired cards. Linked cards can communicate over large (unlimited) distances and across dimensions. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/manual.md b/src/main/resources/assets/opencomputers/doc/en_us/item/manual.md index b8b7323c22..22aa2f3584 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/manual.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/manual.md @@ -1,6 +1,6 @@ # Manual -![A good read.](oredict:oc:manual) +![A good read.](oredict:opencomputers:manual) The thing you're reading right now! The manual contains a wealth of information about OpenComputers (and possibly more). If you need information on an item or block in the mod, look no further! Scroll down to learn how to use (mouse wheel or the scroll bar to the right). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/mfu.md b/src/main/resources/assets/opencomputers/doc/en_us/item/mfu.md index e288f6653b..6b03de96b7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/mfu.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/mfu.md @@ -1,6 +1,6 @@ # MFU -![You will never know the true meaning of this acronym.](oredict:oc:mfu) +![You will never know the true meaning of this acronym.](oredict:opencomputers:mfu) This upgrade acts as a remote [adapter](../block/adapter.md). Click while sneaking onto any side of any block to bind it to a specific position. Then, place it into an adapter nearby (the range is very limited) and it will act as if the adapter was placed right next to the specific side you bound it to! diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/microcontrollercase1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/microcontrollercase1.md index 92045902be..f029e76db4 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/microcontrollercase1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/microcontrollercase1.md @@ -1,6 +1,6 @@ # Microcontroller Case -![It's so cute.](oredict:oc:microcontrollerCase1) +![It's so cute.](oredict:opencomputers:microcontrollerCase1) The Microcontroller case is the base part when building [microcontrollers](../block/microcontroller.md) in the [assembler](../block/assembler.md). [Microcontrollers](../block/microcontroller.md) are very primitive [computers](../general/computer.md). They may only contain a very limited number of components, and are intended to be used in very specific use-cases, such as transforming or reacting to redstone signals, or processing network messages. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/nanomachines.md b/src/main/resources/assets/opencomputers/doc/en_us/item/nanomachines.md index aa1f48ce76..4130f339ab 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/nanomachines.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/nanomachines.md @@ -1,6 +1,6 @@ # Nanomachines -![Nanomachines, son.](oredict:oc:nanomachines) +![Nanomachines, son.](oredict:opencomputers:nanomachines) These little guys interface with your nervous system to make you harder, better, faster, stronger, or kill you. Sometimes both at the same time! Put simply, nanomachines provide a power driven system for applying buffs (and debuffs) to the player they reside in. To "install" nanomachines, eat them! diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/navigationupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/navigationupgrade.md index 4ce1d4ef5d..63f3ef0636 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/navigationupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/navigationupgrade.md @@ -1,6 +1,6 @@ # Navigation Upgrade -![I'm lost. Again.](oredict:oc:navigationUpgrade) +![I'm lost. Again.](oredict:opencomputers:navigationUpgrade) The navigation upgrade provides location and orientation information to devices it is installed in. The coordinates the upgrade provides are relative to the center of the map that was used to craft the upgrade, and the functional range is based on the size of that map. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/numpad.md b/src/main/resources/assets/opencomputers/doc/en_us/item/numpad.md index 05ff6ade73..4eaf74dd19 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/numpad.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/numpad.md @@ -1,5 +1,5 @@ # Numeric Keypad -![Check for fingerprints.](oredict:oc:materialNumPad) +![Check for fingerprints.](oredict:opencomputers:materialNumPad) The Numeric keypad is part of every [keyboard](../block/keyboard.md). It allows you to enter numbers. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/pistonupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/pistonupgrade.md index 85c62dd44b..c12ea3f1c3 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/pistonupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/pistonupgrade.md @@ -1,6 +1,6 @@ # Piston Upgrade -![Push it.](oredict:oc:pistonUpgrade) +![Push it.](oredict:opencomputers:pistonUpgrade) The piston upgrade allows some devices to act very much like a vanilla piston. When installed, a component with a single method, `push()`, becomes available. When called the device will then try to push the block in its forward facing direction. For [robots](../block/robot.md) and [microcontrollers](../block/microcontroller.md), this is the front face; for [tablets](tablet.md), it will use the player's facing direction. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/printedcircuitboard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/printedcircuitboard.md index fdd266165b..53eda41e34 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/printedcircuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/printedcircuitboard.md @@ -1,5 +1,5 @@ # Printed Circuit Board -![AKA PCB](oredict:oc:materialCircuitBoardPrinted) +![AKA PCB](oredict:opencomputers:materialCircuitBoardPrinted) The printed circuit board is, next to the [transistor](transistor.md), one of the most basic crafting materials in OpenComputers. It is used as a basis for many components, such as [cards](card.md) and a large number of [blocks](../block/index.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/ram1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/ram1.md index cd54adc4eb..9636b4ea1f 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/ram1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/ram1.md @@ -1,6 +1,6 @@ # Memory -![Do you remember, dancing in September~](oredict:oc:ram1) +![Do you remember, dancing in September~](oredict:opencomputers:ram1) Memory is, like the [CPU](cpu1.md), an essential part in all [computers](../general/computer.md). Depending on the [CPU](cpu1.md)'s architecture, the memory has a very essential effect on what a [computer](../general/computer.md) can and cannot do. For the standard Lua architecture, for example, it controls the actual amount of memory Lua scripts can use. This means that to run larger and more memory-intensive programs, you will need more memory. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/rawcircuitboard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/rawcircuitboard.md index ac00250eab..0366c08be5 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/rawcircuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/rawcircuitboard.md @@ -1,5 +1,5 @@ # Raw Circuit Board -![Not sushi.](oredict:oc:materialCircuitBoardRaw) +![Not sushi.](oredict:opencomputers:materialCircuitBoardRaw) Intermediary crafting material, used for crafting [circuit boards](circuitBoard.md) (or [printed circuit boards](printedCircuitBoard.md), depending on the recipe set being used). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/redstonecard1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/redstonecard1.md index 2110c6b84f..7b6067383f 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/redstonecard1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/redstonecard1.md @@ -1,6 +1,6 @@ # Redstone Card -![Seeing red.](oredict:oc:redstoneCard1) +![Seeing red.](oredict:opencomputers:redstoneCard1) The redstone card allows [computers](../general/computer.md) to read and emit analog redstone signal in adjacent blocks. When an incoming signal strength changes, a signal is injected into the [computer](../general/computer.md). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/server1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/server1.md index 00c3544753..be7aafb537 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/server1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/server1.md @@ -1,6 +1,6 @@ # Server -![Serves u right.](oredict:oc:server1) +![Serves u right.](oredict:opencomputers:server1) Servers are a form of higher tier [computer](../general/computer.md). They can be configured by holding them in the hand and using them - like opening a backpack or Ender pouch, for example. Servers can also be configured after having been installed into a [rack](../block/rack.md) by activating them (aiming at the corresponding position on the front face on the [rack](../block/rack.md)). To operate, the server has to be placed inside a [rack](../block/rack.md). For more information see the [rack](../block/rack.md) entry. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/signupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/signupgrade.md index 944bd24b64..7fdb9944b1 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/signupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/signupgrade.md @@ -1,5 +1,5 @@ # Sign I/O -![I see the signs on the wall.](oredict:oc:signUpgrade) +![I see the signs on the wall.](oredict:opencomputers:signUpgrade) This upgrade allows devices to interact with signs in the world. It allows reading the current message on the sign as well as changing the message on the sign (if permitted. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/solargeneratorupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/solargeneratorupgrade.md index 6740d5e693..c382e71479 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/solargeneratorupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/solargeneratorupgrade.md @@ -1,6 +1,6 @@ # Solar Generator -![Walking on the sun.](oredict:oc:solarGeneratorUpgrade) +![Walking on the sun.](oredict:opencomputers:solarGeneratorUpgrade) The solar generator upgrade can be installed in devices such as [robots](../block/robot.md), [drones](drone.md) and [tablets](tablet.md) to passively generate energy. It will only work while the device is exposed to direct sunlight; a device in an enclosed area or an area affected by weather will not generate energy. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/stickypistonupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/stickypistonupgrade.md index 318622ad3e..c1edfea4e7 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/stickypistonupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/stickypistonupgrade.md @@ -1,6 +1,6 @@ # Sticky Piston Upgrade -![Push it. Pull it.](oredict:oc:stickyPistonUpgrade) +![Push it. Pull it.](oredict:opencomputers:stickyPistonUpgrade) The sticky piston upgrade is an upgrade to the [Piston Upgrade](pistonupgrade.md) which allows some devices to act very much like a vanilla sticky piston. When installed, a piston component becomes available. Its methods are `push()` and `pull()`. When these are called the device will act like a vanilla sticky piston and try to push or pull the block in its forward facing direction. For [robots](../block/robot.md) and [microcontrollers](../block/microcontroller.md), this is the front face; for [tablets](tablet.md), it will use the player's facing direction. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/tablet.md b/src/main/resources/assets/opencomputers/doc/en_us/item/tablet.md index eab94a8166..3d66013e9c 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/tablet.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/tablet.md @@ -1,6 +1,6 @@ # Tablet -![Touch me if you can.](item:OpenComputers:item@68) +![Touch me if you can.](item:opencomputers:tablet) Tablets are built by placing a [tablet case](tabletCase1.md) into an [assembler](../block/assembler.md), configuring as desired and assembling it. Tablets act as portable computers that cannot directly interact with the world - for example, basic [redstone cards](redstoneCard1.md) do not work in them. A number of upgrades do, such as the [sign i/o](signUpgrade.md) upgrade or the [piston](pistonUpgrade.md) upgrade. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/tabletcase1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/tabletcase1.md index 923c02aac4..3ee4513c20 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/tabletcase1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/tabletcase1.md @@ -1,6 +1,6 @@ # Tablet Case -![Doesn't bend.](oredict:oc:tabletCase1) +![Doesn't bend.](oredict:opencomputers:tabletCase1) The tablet case is the base part when building [tablets](tablet.md) in the [assembler](../block/assembler.md). [Tablets](tablet.md) are very compact and portable [computers](../general/computer.md). They can host a small number of select upgrades, but cannot interact with the world like [computer cases](../block/case1.md) can (using simple [network cards](lanCard.md) or [redstone cards](redstoneCard1.md) for example). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/tankcontrollerupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/tankcontrollerupgrade.md index 57bbda9b72..0de4182bb6 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/tankcontrollerupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/tankcontrollerupgrade.md @@ -1,6 +1,6 @@ # Tank Controller -![Fluid routing.](oredict:oc:tankControllerUpgrade) +![Fluid routing.](oredict:opencomputers:tankControllerUpgrade) The tank controller upgrade is to fluid tanks what the [inventory controller upgrade](inventoryControllerUpgrade.md) is to normal inventories. It allows devices to query more detailed information about tanks inside and next to them. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/tankupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/tankupgrade.md index 23745e61a0..f83b74e3c9 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/tankupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/tankupgrade.md @@ -1,5 +1,5 @@ # Tank Upgrade -![Suck it.](oredict:oc:tankUpgrade) +![Suck it.](oredict:opencomputers:tankUpgrade) The tank upgrade allows devices to store fluids. Each tank can only hold a single type of fluid, and provides a volume of 16 buckets (16000mB). [Robots](../block/robot.md) and [drones](drone.md) can drain liquids from the world and from other fluid tanks, and can fill the fluids back into fluid tanks, and when supported by the fluid, place them back into the world. There is no limit to the number of tanks that can be installed in a device. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/terminal.md b/src/main/resources/assets/opencomputers/doc/en_us/item/terminal.md index 8091c1dd18..f6b6247705 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/terminal.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/terminal.md @@ -1,6 +1,6 @@ # Remote Terminal -![Remote access.](oredict:oc:terminal) +![Remote access.](oredict:opencomputers:terminal) The remote terminal can be used to remotely control computers via [terminal servers](terminalServer.md). To use it, activate a [terminal server](terminalServer.md) that is installed in a [rack](../block/rack.md) (click on the [rack](../block/rack.md) block in the world, targeting the [terminal server](terminalServer.md) to bind the terminal to). diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/terminalserver.md b/src/main/resources/assets/opencomputers/doc/en_us/item/terminalserver.md index 53cedf2e32..f009b00145 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/terminalserver.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/terminalserver.md @@ -1,5 +1,5 @@ # Terminal Server -![Remote Viewing](oredict:oc:terminalServer) +![Remote Viewing](oredict:opencomputers:terminalServer) Terminal servers provides a virtual [screen](../block/screen1.md) and [keyboard](../block/keyboard.md) which can be controlled via [remote terminals](terminal.md). See the [remote terminal](terminal.md) manual entry for more information. Terminal servers must be installed in a [rack](../block/rack.md) to function. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/texturepicker.md b/src/main/resources/assets/opencomputers/doc/en_us/item/texturepicker.md index 9a3e183fbd..1297d3d2e1 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/texturepicker.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/texturepicker.md @@ -1,6 +1,6 @@ # Texture Picker -![What do you mean, it's just a re-skin?](oredict:oc:texturePicker) +![What do you mean, it's just a re-skin?](oredict:opencomputers:texturePicker) The texture picker is very useful when making models for your [3D printer](../block/printer.md). It allows getting the texture name of textures used by blocks in the world, simply by (sneak-)activating them with the tool. Disclaimer: for blocks that use special rendering, such as chests, this may not work. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/tractorbeamupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/tractorbeamupgrade.md index ea1535f2e8..98329e081f 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/tractorbeamupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/tractorbeamupgrade.md @@ -1,5 +1,5 @@ # Tractor Beam -![Beam me up.](oredict:oc:tractorBeamUpgrade) +![Beam me up.](oredict:opencomputers:tractorBeamUpgrade) The tractor beam upgrade allows devices to pick up items in a three block radius around them. This can be highly useful when using [robots](../block/robot.md) in tree or other farms, or when having them use tools that break multiple blocks around them (such as Tinker's Construct tools). Each operation will try to suck a single item stack in range and consume some energy. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/tradingupgrade.md b/src/main/resources/assets/opencomputers/doc/en_us/item/tradingupgrade.md index 8a599707cb..2671d4c439 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/tradingupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/tradingupgrade.md @@ -1,5 +1,5 @@ # Trading Upgrade -![Equivalent Exchange](oredict:oc:tradingUpgrade) +![Equivalent Exchange](oredict:opencomputers:tradingUpgrade) The trading upgrade enables automatic trading with merchants, such as villagers. It can be used in agents such as [robots](../block/robot.md) and [drones](drone.md) and provides capabilities to identify available trades from nearby merchants, retrieve information on individual trade offers, and finally for performing trades. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/transistor.md b/src/main/resources/assets/opencomputers/doc/en_us/item/transistor.md index edef8d4b9e..8d3e75f42b 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/transistor.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/transistor.md @@ -1,5 +1,5 @@ # Transistor -![I think I've used up all my references.](oredict:oc:materialTransistor) +![I think I've used up all my references.](oredict:opencomputers:materialTransistor) The transistor is one of the most basic crafting ingredients in OpenComputers. It is mainly used to craft [microchips](chip1.md) and other electronic goodies. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/upgradecontainer1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/upgradecontainer1.md index 2a704973ad..dd847a1916 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/upgradecontainer1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/upgradecontainer1.md @@ -1,5 +1,5 @@ # Upgrade Container -![Can haz upgrade.](oredict:oc:upgradeContainer1) +![Can haz upgrade.](oredict:opencomputers:upgradeContainer1) The upgrade container is a container type upgrade for [robots](../block/robot.md), that provides a slot in the finished [robots](../block/robot.md) into which normal upgrades can be placed. The maximum tier of upgrade that slot can hold is equal to the tier of the container. Unlike normal upgrades, the complexity of containers is twice their tier. Refer to [robot](../block/robot.md) and [assembler](../block/assembler.md) documentation on complexity. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/wlancard1.md b/src/main/resources/assets/opencomputers/doc/en_us/item/wlancard1.md index c6b69aed85..669547f0db 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/wlancard1.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/wlancard1.md @@ -1,6 +1,6 @@ # WLAN Card -![May cause cancer. May not.](oredict:oc:wlanCard2) +![May cause cancer. May not.](oredict:opencomputers:wlanCard2) The wireless network card is an upgraded [network card](lanCard.md) that can send and receive wireless network messages. Tier two cards can also send and receive wired messages. The signal strength directly controls the distance up to which a sent message can be received, where the strength is equal to the distance in blocks. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/worldsensorcard.md b/src/main/resources/assets/opencomputers/doc/en_us/item/worldsensorcard.md index 168d1e93d6..b101dd009a 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/worldsensorcard.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/worldsensorcard.md @@ -1,5 +1,5 @@ # World Sensor Card -![To boldly go...](oredict:oc:worldSensorCard) +![To boldly go...](oredict:opencomputers:worldSensorCard) The world sensor card allows reading of atmospheric information as well as gravity on different planets added by Galacticraft. This can be useful for [robots](../block/robot.md) or [drones](drone.md) operating in space. diff --git a/src/main/resources/assets/opencomputers/doc/en_us/item/wrench.md b/src/main/resources/assets/opencomputers/doc/en_us/item/wrench.md index b26d7922e5..696c1cf4bc 100644 --- a/src/main/resources/assets/opencomputers/doc/en_us/item/wrench.md +++ b/src/main/resources/assets/opencomputers/doc/en_us/item/wrench.md @@ -1,5 +1,5 @@ # Scrench -![Made in Swiss.](oredict:oc:wrench) +![Made in Swiss.](oredict:opencomputers:wrench) Like pretty much any other technology-focused mod, OpenComputers has it's own version of a wrench tool. In this case, it is a hybrid of a screwdriver and a wrench, that looks like it's incredibly awkward to use. It can be used to rotate most blocks, and is also compatible with most other mods' blocks that can be interacted with by using wrench-like tools. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/accessPoint.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/accessPoint.md index cda879aa04..a53c9bb19c 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/accessPoint.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/accessPoint.md @@ -1,6 +1,6 @@ # Point d'accès -![AAA](oredict:oc:accessPoint) +![AAA](oredict:opencomputers:accessPoint) *Ce bloc est déprécié et sera retiré dans une version future.* Transformez les en [relai](relay.md) pour éviter de les perdre. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/adapter.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/adapter.md index e451559f6d..c3614096fb 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/adapter.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/adapter.md @@ -1,6 +1,6 @@ # Adaptateur -![Maintenant, avec 100% de plus de tout.](oredict:oc:adapter) +![Maintenant, avec 100% de plus de tout.](oredict:opencomputers:adapter) L'adaptateur permet aux [ordinateurs](../general/computer.md) d'interagir avec des blocs de Minecraft Vanilla ou d'autres mods. Les blocs supportés placés contre l'adaptateur s'afficheront en tant que composants sur les [ordinateurs](../general/computer.md) connectés à l'adaptateur. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/assembler.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/assembler.md index fe84927051..7662f7d703 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/assembler.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/assembler.md @@ -1,6 +1,6 @@ # Assembleur électronique -![Harder, better, faster, stronger.](oredict:oc:assembler) +![Harder, better, faster, stronger.](oredict:opencomputers:assembler) L'assembleur est une table avancée qui peut être utilisée pour construire des appareils électroniques plus complexes, comme les [robots](robot.md), les [drones](../item/drone.md) et les [tablettes](../item/tablet.md). Il nécessite une grande quantité d'énergie pour assembler des appareils, il est donc recommandé de lui fournir suffisament d'énergie avec un [capaciteur](capacitor.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/cable.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/cable.md index 573434e902..1753f9cd55 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/cable.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/cable.md @@ -1,6 +1,6 @@ # Câble -![Salade de câbles.](oredict:oc:cable) +![Salade de câbles.](oredict:opencomputers:cable) Le câble à connecter des [ordinateurs](../general/computer.md) et des machines éloignés les uns des autres. Si vous avez un système compact où tous les composants sont en contact (directement ou indirectement, la plupart des blocs du mod se comportent également de la même manière que les câbles), vous n'aurez généralement pas besoin de câbles. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/capacitor.md index 5304cc37b0..1af8e18174 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/capacitor.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/capacitor.md @@ -1,6 +1,6 @@ # Capaciteur -![Au delà des 8000.](oredict:oc:capacitor) +![Au delà des 8000.](oredict:opencomputers:capacitor) Le capaciteur emmagasine de l'énergie qui sera utilisée par le réseau, en se comportant comme un tampon d'énergie au besoin. Contrairement à la conversion de l'énergie d'autres mods vers l'énergie interne à OpenComputers (en utilisant un [convertisseur énergétique](powerConverter.md) par exemple), le transfert d'énergie dans un sous-réseau est instantané. Posséder un tampon d'énergie interne sera utile pour des tâches qui nécessitent beaucoup d'énergie, comme l'[assemblage](assembler.md) et/ou la [charge](charger.md) d'appareils comme les [robots](robot.md) ou les [drones](../item/drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/case1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/case1.md index d76af8b20f..0221c16ade 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/case1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/case1.md @@ -1,6 +1,6 @@ # Boîtier d'ordinateur -![Ah qu'est-ce qu'on est serré...](oredict:oc:case1) +![Ah qu'est-ce qu'on est serré...](oredict:opencomputers:case1) Les boîtiers d'ordinateur existent en 3 niveaux différents, ce qui limite les composants qui peuvent y être insérés. Un niveau supplémentaire existe aussi, seulement pour le mode créatif. Les boîtiers d'ordinateur peuvent également être placés dans un [assembleur électronique](assembler.md) pour construire des [robots](robot.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/chameliumBlock.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/chameliumBlock.md index e437c066eb..73bf1ed82b 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/chameliumBlock.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/chameliumBlock.md @@ -1,6 +1,6 @@ # Bloc de Chamélium -![Tellement... blanc.](oredict:oc:chameliumBlock) +![Tellement... blanc.](oredict:opencomputers:chameliumBlock) Quelques morceaux de [chamélium](../item/chamelium.md) peuvent être combinés pour fournir un bloc monochrome à des fins décoratives. Les blocs de chamélium peuvent aussi être teintés avec n'importe laquelle des 16 couleurs de Minecraft. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/charger.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/charger.md index 824302c285..e3580c106e 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/charger.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/charger.md @@ -1,6 +1,6 @@ # Chargeur -![LEEROOOOOOOOOY](oredict:oc:charger) +![LEEROOOOOOOOOY](oredict:opencomputers:charger) Le chargeur est utilisé pour charger des appareils comme les [robots](robot.md), les [drones](../item/drone.md) et les [tablettes](../item/tablet.md). Un chargeur doit être activé en lui appliquant un signal de redstone. La vitesse de charge est basée sur la force du signal de redstone appliqué, avec une force de 15 donnant une vitesse de charge de 100%. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/disassembler.md index 8273de5f46..2fdcaeeb8b 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/disassembler.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/disassembler.md @@ -1,6 +1,6 @@ # Désassembleur -![Construire, détruire](oredict:oc:disassembler) +![Construire, détruire](oredict:opencomputers:disassembler) Le désassembleur peut être utilisé pour déconstruire la plupart des objets d'OpenComputers en leurs éléments d'origine. C'est particulièrement utile pour récupérer des matériaux à partir d'anciens éléments qui ne sont plus utiles, ou pour déconstruire des appareils qui ne sont plus nécessaire ou qui ont été mal montés (ex : un [robot](robot.md) sans [système d'exploitation](../general/openOS.md)). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/diskDrive.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/diskDrive.md index e369473cce..53df9ef779 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/diskDrive.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/diskDrive.md @@ -1,6 +1,6 @@ # Lecteur de disquettes -![Silence, on tourne !](oredict:oc:diskDrive) +![Silence, on tourne !](oredict:opencomputers:diskDrive) Le lecteur de disquettes peut être utilisé pour lire des [disquettes](../item/floppy.md) en se servant d'un [ordinateur](../general/computer.md) connecté au lecteur de disquette. C'est très utile pour démarrer, car les niveaux les plus inférieurs de [boîtier d'ordinateur](case1.md) n'ont pas d'emplacement pour disquettes pré-construit, et vous aurez besoin d'un système d'exploitation pour démarrer l'[ordinateur](../general/computer.md). Un disque d'[OpenOS](../general/openOS.md) peut être fabriqué en utilisant une [disquette](../item/floppy.md) vierge et un [manuel](../item/manual.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/geolyzer.md index b4cb8067bb..45edb2d187 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/geolyzer.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/geolyzer.md @@ -1,6 +1,6 @@ # Géolyseur -![Pierre qui roule...](oredict:oc:geolyzer) +![Pierre qui roule...](oredict:opencomputers:geolyzer) Le géolyseur peut être utilisé par les [ordinateurs](../general/computer.md) pour scanner le terrain autour du géolyseur par la dureté approximative des blocs. Cela peut être utile pour générer des cartes du terrain à afficher sur un [projecteur d'hologramme](hologram1.md) ou pour détecter des blocs potentiellement précieux (les minerais sont généralement plus durs que la terre et la pierre). Les résultats du scan du géolyseur ont une certaine quantité de bruit ajoutée; en théorie, de nombreux scans peuvent être effectués pour obtenir une meilleure lecture du niveau de dureté d'un bloc. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/hologram1.md index 482d069853..e78309301a 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/hologram1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/hologram1.md @@ -1,6 +1,6 @@ # Projecteur d'hologramme -![Is this the real life? Is this just fantasy?](oredict:oc:hologram1) +![Is this the real life? Is this just fantasy?](oredict:opencomputers:hologram1) Le projecteur d'hologramme est un afficheur volumétrique, c'est à dire qu'il fournit un tableau de voxels en trois dimensions qui peuvent être contrôlés individuellement par un [ordinateur](../general/computer.md) auquel il serait connecté. Le deuxième niveau de projecteur, même s'il a la même résolution que le projecteur de niveau 1, gère l'affichage de chaque voxel avec trois couleurs définissable par l'utilisateur. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/keyboard.md index b587ed71ea..c9ca8b535d 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/keyboard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/keyboard.md @@ -1,6 +1,6 @@ # Clavier -![AZERTY](oredict:oc:keyboard) +![AZERTY](oredict:opencomputers:keyboard) Un clavier est requis pour saisir du texte sur l'[écran](screen1.md), qu'ils existent physiquement dans le monde ou intégrés à un appareil comme un [robot](robot.md) ou une [tablette](../item/tablet.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/motionSensor.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/motionSensor.md index 21cbacb66f..544fbbf5df 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/motionSensor.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/motionSensor.md @@ -1,6 +1,6 @@ # Détecteur de mouvement -![Ne. Clignez. Pas. Des. Yeux.](oredict:oc:motionSensor) +![Ne. Clignez. Pas. Des. Yeux.](oredict:opencomputers:motionSensor) Le détecteur de mouvement permet aux [ordinateurs](../general/computer.md) de détecter le mouvement des entités vivantes. Si une entité se déplace plus vite qu'un seuil défini, un signal sera injecté dans les [ordinateurs](../general/computer.md) connectés au détecteur de mouvement. Le seuil peut être configuré en utilisant l'API des composants que le détecteur de mouvement expose aux ordinateurs connectés. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/netSplitter.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/netSplitter.md index 0b395c0142..7b71c9435e 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/netSplitter.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/netSplitter.md @@ -1,6 +1,6 @@ # Répartiteur réseau -![*.net *.split](oredict:oc:netSplitter) +![*.net *.split](oredict:opencomputers:netSplitter) Le répartiteur réseau est un appareil qui permet de contrôler la connectivité entre des sous-réseaux. A la différence du [relai](relay.md) ou du [convertisseur énergétique](powerConverter.md), il connecte directement entre eux des sous-réseaux voisins, c'est à dire qu'il est possible d'accéder aux composants des sous-réseaux. La connectivité de chaque face peut être activée en utilisant une clé (ex: le [crisseur](../item/wrench.md)). Quand un signal de redstone est appliqué au répartiteur réseau, la connectivité de toutes les faces est inversée. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerConverter.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerConverter.md index 91592a8638..fc6a583c6e 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerConverter.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerConverter.md @@ -1,5 +1,5 @@ # Convertisseur énergétique -![L'un des nôtres ? L'un des nôtres !](oredict:oc:powerConverter) +![L'un des nôtres ? L'un des nôtres !](oredict:opencomputers:powerConverter) Le convertisseur énergétique est la manière la plus rapide de convertir de l'énergie provenant d'autres mods en énergie interne à OpenComputers. Si vous utilisez un seul ordinateur, vous n'aurez probablement pas besoin de convertisseur. Si vous avez un grand groupe de capaciteurs dont vous utilisez l'énergie de temps en temps, vous n'en aurez sûrement pas besoin non plus. Cependant, si vous souhaitez alimenter directement un [assembleur électronique](assembler.md) ou un [chargeur](charger.md), c'est généralement une bonne idée d'utiliser un convertiseeur au lieu de les connecter directement à une source externe d'énergie. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerDistributor.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerDistributor.md index fa717d3b5b..2b98941257 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerDistributor.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/powerDistributor.md @@ -1,5 +1,5 @@ # Distributeur énergétique -![Le pouvoir au peuple.](oredict:oc:powerDistributor) +![Le pouvoir au peuple.](oredict:opencomputers:powerDistributor) Le distributeur énergétique distribue l'énergie d'un espace de stockage partagé (comme un [capaciteur](capacitor.md)), permettant à de nombreux sous-réseaux de partager leur énergie sans que leurs composants soient exposés aux ordinateurs des autres sous-réseaux. Il fonctionne en répartissant équitablement l'énergie dans tous les sous-réseaux auquel il est connecté, de façon à ce que la quantité *relative* d'énergie est la même dans chacun. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/printer.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/printer.md index 9b47a78b07..7582613551 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/printer.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/printer.md @@ -1,6 +1,6 @@ # Imprimante 3D -![L'impression en 2D, c'est tellement dépassé.](oredict:oc:printer) +![L'impression en 2D, c'est tellement dépassé.](oredict:opencomputers:printer) Les imprimantes 3D vous permettent d'imprimer n'importe quel bloc de n'importe forme, avec n'importe quelle texture. Pour démarrer avec les imprimantes 3D, vous devrez placer un bloc d'imprimante 3D à côté d'un ordinateur. Cela vous donnera accès à l'API de composant `printer3d`, ce qui permet de paramétrer et d'imprimer des [modèles](print.md) en utilisant les fonction fournies. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/raid.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/raid.md index 6a849e991e..b8b0fa5d59 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/raid.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/raid.md @@ -1,6 +1,6 @@ # Raid -![Une instance à 40.](oredict:oc:raid) +![Une instance à 40.](oredict:opencomputers:raid) Le bloc de RAID peut accueillir 3 [disques dur](../item/hdd1.md) qui seront combinés en un seul système de fichiers. Ce système de fichiers combinés a la taille de la somme des capacités des [disques dur](../item/hdd1.md) individuels, et est disponible pour tous les [ordinateurs](../general/computer.md) connectés au RAID. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/redstone.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/redstone.md index ae35bfc29c..f8d72aeb82 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/redstone.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/redstone.md @@ -1,6 +1,6 @@ # Redstone E/S -![Salut Red.](oredict:oc:redstone) +![Salut Red.](oredict:opencomputers:redstone) Le bloc d'E/S de redstone peut être utilisé pour lire et émettre des signaux de redstone à distance. Il se comporte comme un hybride des [cartes de redstone](../item/redstoneCard1.md) de niveau 1 et 2 : il peut aussi bien lire et émettre des signaux analogiques que des signaux empaquetés (bundle), mais il ne peut pas lire ou émettre de signaux redstone sans-fil. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/relay.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/relay.md index 6e70c3eee3..bcad6afe33 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/relay.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/relay.md @@ -1,6 +1,6 @@ # Relai -![Construit des ponts.](oredict:oc:relay) +![Construit des ponts.](oredict:opencomputers:relay) Le relai peut être utilisé pour permettre à différents sous-réseaux de s'envoyer des messages réseau entre eux, sans exposer leurs composants aux [ordinateurs](../general/computer.md) des autres réseaux. Maintenir l'état "local" d'un composant est généralement une bonne idée, pour éviter aux [ordinateurs](../general/computer.md) d'utiliser le mauvais [écran](screen1.md) ou pour éviter qu'une surcharge de composants survienne (ce qui provoque le crash de l'[ordinateur](../general/computer.md) et l'empêche de démarrer). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/screen1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/screen1.md index e58a88981e..f8822c8033 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/screen1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/screen1.md @@ -1,6 +1,6 @@ # Ecrans -![Tu vois ça ?](oredict:oc:screen1) +![Tu vois ça ?](oredict:opencomputers:screen1) Un écran est utilisé en combinaison avec une [carte graphique](../item/graphicsCard1.md), pour permettre aux [ordinateurs](../general/computer.md) d'afficher du texte. Les différents niveaux d'écrans ont différentes capacités, comme le support de différentes résolutions et couleurs. La qualité des écrans va d'une faible résolution en affichage monochrome à une haute résolution en 256 couleurs. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/serverRack.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/serverRack.md index 681fcc50f6..288a0f4197 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/serverRack.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/serverRack.md @@ -1,6 +1,6 @@ # Support de serveur -![Logement gratuit.](oredict:oc:serverRack) +![Logement gratuit.](oredict:opencomputers:serverRack) Un support de serveur peut contenir jusqu'à 4 [serveurs](../item/server1.md). Un [serveur](../item/server1.md) est un [ordinateur](../general/computer.md) de plus haut niveau, qui peut seulement être lancé dans un support de serveur. Les [serveurs](../item/server1.md) peuvent être contrôlés à distance avec un [terminal à distance](../item/terminal.md). Le nombre de [terminaux à distance](../item/terminal.md) qui peuvent être connectés à un seul [serveur](../item/server1.md) à la fois dépend du niveau du [serveur](../item/server1.md). La distance jusqu'à laquelle le [terminal à distance](../item/terminal.md) fonctionne peut être configurée dans l'interface du support. De plus grandes valeurs nécessitent plus d'énergie. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/switch.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/switch.md index c5421f8985..beb888c171 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/switch.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/switch.md @@ -1,6 +1,6 @@ # Routeur -![[relays](relay.md).](oredict:oc:switch) +![[relays](relay.md).](oredict:opencomputers:switch) *Ce bloc est déprécié et sera retiré dans une version future.* Transformez les en [relai](relay.md) pour éviter de les perdre. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/transposer.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/transposer.md index 1d743969d5..a83ece0a8e 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/transposer.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/transposer.md @@ -1,6 +1,6 @@ # Transposeur -![Quel poseur!](oredict:oc:transposer) +![Quel poseur!](oredict:opencomputers:transposer) Le transposeur fait le lien entre les entonnoirs controlés par la redstone et les [robots](robot.md), ce qui permet le transfert d'objets et de fluides entre des blocs voisins contrôlé par [ordinateur](../general/computer.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/block/waypoint.md b/src/main/resources/assets/opencomputers/doc/fr_fr/block/waypoint.md index de69a8be8b..4ea7bdfb07 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/block/waypoint.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/block/waypoint.md @@ -1,6 +1,6 @@ # Point de passage -!["Par là !" - "Non, par là !"](oredict:oc:waypoint) +!["Par là !" - "Non, par là !"](oredict:opencomputers:waypoint) Le point de passage n'a aucune utilité en soi, mais dans la façon dont il peut être utilisé. Les [améliorations de navigation](../item/navigationUpgrade.md) peuvent détecter les points de passage, ainsi les appareils équipés d'une amélioration de navigation peuvent utiliser ces points de passage pour parcourir le monde. C'est particulièrement utile pour écrire des programmes facilement ré-utilisables par des appreils comme les [robots](robot.md) et les [drones](../item/drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/general/example.md b/src/main/resources/assets/opencomputers/doc/fr_fr/general/example.md index c0937a7a79..8c17aeea08 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/general/example.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/general/example.md @@ -4,13 +4,13 @@ Voici un peu de texte de test pour la version de Markdown supportée par le syst ![Ceci est une info-bulle...](opencomputers:textures/gui/printer_ink.png) ![Ceci est une info-bulle...](opencomputers:/textures/gui/printer_material.png) *Ceci* est du texte en *italique*, ~~barré~~ peut-être **un peu** de texte **en gras**. Est-ce que _c'est souligné _? Oh, non, _c'est aussi en italique!_ Bon, c'est [un lien](../index.md). -![C'est rendu en direct.](oredict:oc:assembler) +![C'est rendu en direct.](oredict:opencomputers:assembler) ## Entête plus petite [avec un *lien* aussi mais cette __fois__ plus long](../block/adapter.md) -![Ceci est une autre info-bulle.](item:OpenComputers:item@23) +![Ceci est une autre info-bulle.](item:opencomputers:transistor) un peu de texte directement au dessus de l'afficheur d'objet pour tester l'espacement -![Toutes ces couleurs.](oredict:craftingPiston) +![Toutes ces couleurs.](oredict:forge/piston) un peu de texte directement en dessous de l'afficheur d'objet pour tester l'espacement Ceci est en *italique @@ -42,9 +42,9 @@ asdasd ![oh mon dieu, la récursion !](img/example.png) qweqwe Et finalement, [c'est un lien !](https://avatars1.githubusercontent.com/u/514903). -![image de l'objet inexistante](item:ça n'existe pas) -![image de l'objet inexistante](block:ça n'existe pas) -![image de l'objet inexistante](oredict:ça n'existe pas) +![image de l'objet inexistante](item:this_is_broken) +![image de l'objet inexistante](block:this_is_broken) +![image de l'objet inexistante](oredict:this_is_broken) tests de retour à la ligne 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 @@ -53,17 +53,17 @@ tests de retour à la ligne * 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 - `123456789012345678901234567890.12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890` -c'est un test pour une![](oredict:oc:cpu1)une image dans une lignekakakakalalsd 123 as +c'est un test pour une![](oredict:opencomputers:cpu1)une image dans une lignekakakakalalsd 123 as -c'est un test pour une![](oredict:oc:cpu1) +c'est un test pour une![](oredict:opencomputers:cpu1) une image avec un retour à la ligne après c'est un test pour une -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) une image entre deux lignes c'est un test pour une -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) une image entre deux lignes vides diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/fr_fr/general/quickstart.md index 133f50ec5b..9eba8fb45f 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/general/quickstart.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/general/quickstart.md @@ -6,7 +6,7 @@ Aussi connu en tant que "comment construire votre premier ordinateur". Pour fair Premièrement, vous aurez besoin d'un [boîtier](../block/case1.md). C'est le bloc qui contiendra tous les composants, en définissant le comportement de l'ordinateur que vous construisez. -![Un boîtier d'ordinateur de niveau 2.](oredict:oc:case2) +![Un boîtier d'ordinateur de niveau 2.](oredict:opencomputers:case2) Par exemple, vous aurez besoin de choisir quel niveau de [carte graphique](../item/graphicsCard1.md) vous voulez utiliser, si vous avez besoin d'une [carte réseau](../item/lanCard.md), une [carte de redstone](../item/redstoneCard1.md) ou, si vous faites des essais en mode créatif, peut être même une [carte de débogueur](../item/debugCard.md). @@ -39,7 +39,7 @@ Maintenant, si vous avez utilisé un [boîtier](../block/case2.md) de niveau 2 c Il vit ! Ou il devrait, en tout cas. Si ce n'est pas le cas quelque chose ne va pas, et vous devriez investiguer en utilisant l'[analyzer](../item/analyzer.md). Mais en supposant qu'il fonctionne maintenant, vous avez presque fini. La partie la plus compliquée est terminée. Tout ce qui reste à faire est de lui permettre d'accepter des entrées, et d'afficher des sorties. Pour permettre à l'[ordinateur](computer.md) d'afficher des informations, vous devrez vous munir d'un [écran](../block/screen1.md) et d'une [carte graphique](../item/graphicsCard1.md). -![Non, ce n'est pas un écran plat.](oredict:oc:screen2) +![Non, ce n'est pas un écran plat.](oredict:opencomputers:screen2) Placez l'[écran](../block/screen1.md) à côté de votre [boîtier](../block/case1.md) ou, à nouveau, connectez le en utilisant des [câbles](../block/cable.md). Puis placez une [carte graphique](../item/graphicsCard1.md) de votre choix dans le [boîtier](../block/case1.md). Vous devriez maintenant voir un curseur clignotant sur l'[écran](../block/screen1.md). Finalement, placez un [clavier](../block/keyboard.md) soit sur l'[écran](../block/screen1.md) lui-même, soit juste en face de l'[écran](../block/screen1.md), pour activer l'entrée de données au [clavier](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/abstractBusCard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/abstractBusCard.md index bd5e7d93f6..3c957c25b5 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/abstractBusCard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/abstractBusCard.md @@ -1,5 +1,5 @@ # Carte de bus abstraite -![Plus de réseau!](oredict:oc:abstractBusCard) +![Plus de réseau!](oredict:opencomputers:abstractBusCard) Cette carte permet aux [ordinateurs](../general/computer.md), aux [serveurs](server1.md) et aux [robots](../block/robot.md) d'interagir avec le bus d'abstraction de StargateTech2. Quand la carte est installée, ces blocs se connecteront au bus d'abstraction et un composant devient disponible aux machines, pour envoyer des messages à travers le bus d'abstraction. Les messages entrants du bus d'abstraction sont convertis en signaux qui sont injectés dans la machine. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/acid.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/acid.md index 93b20ef3f2..9020586237 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/acid.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/acid.md @@ -1,6 +1,6 @@ # Grog -![Un reflux?](oredict:oc:materialAcid) +![Un reflux?](oredict:opencomputers:materialAcid) Cette délicieuse [citation nécessaire] mixture peut être consommée si jamais vous ressentez le besoin de vous... amuser. Ou de détruire votre tube digestif. Ou les deux. Il peut également servir en tant qu'ingrédient pour d'autres objets beaucoup plus utiles. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/alu.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/alu.md index ed6a818835..4d6f93f2c6 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/alu.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/alu.md @@ -1,5 +1,5 @@ # Unité de Logique Arithmétique -![Je être logique !](oredict:oc:materialALU) +![Je être logique !](oredict:opencomputers:materialALU) Elle est utilisée pour fabriquer des composants effectuant des calculs, comme les [processeurs](cpu1.md) et les [cartes graphiques](graphicsCard1.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/analyzer.md index 5d7bd945bf..09d6d5e7c4 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/analyzer.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/analyzer.md @@ -1,6 +1,6 @@ # Analyseur -![Je... ne dois pas... faire... de... mauvaises blagues...](oredict:oc:analyzer) +![Je... ne dois pas... faire... de... mauvaises blagues...](oredict:opencomputers:analyzer) L'analyseur est un outil très pratique pour afficher des informations les blocs liés à OpenComputers. Cliquez simplement sur un bloc (en étant éventuellement accroupi) pour afficher quelques informations dans la zone de chat. Cela va de choses basiques comme l'adresse des composants, aux niveaux d'énergie du sous-réseau dont le bloc fait partie, jusqu'aux informations sur l'erreur qui a mené un [ordinateur](../general/computer.md) à planter, par exemple. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/angelUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/angelUpgrade.md index 2384a61d86..e8e7283602 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/angelUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/angelUpgrade.md @@ -1,5 +1,5 @@ # Amélioration Ange -![Alléluia.](oredict:oc:angelUpgrade) +![Alléluia.](oredict:opencomputers:angelUpgrade) Cette amélioration permet aux [robots](../block/robot.md) de placer des blocs en l'air, sans bloc de soutien. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/apu1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/apu1.md index 9ab4090c17..f999898618 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/apu1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/apu1.md @@ -1,6 +1,6 @@ # Unité de Traitement Accélérée (UTA) -![Unificateur de Tabourets Acrobates.](oredict:oc:apu1) +![Unificateur de Tabourets Acrobates.](oredict:opencomputers:apu1) Cet élément est la parfaite union d'un [processeur](cpu1.md) et d'une [carte graphique](graphicsCard1.md). En utiliser une revient à vous laisser un emplacement de carte supplémentaire. Comme un processeur normal, elle définit l'architecture de l'[ordinateur](../general/computer.md), et le nombre de composants qui peuvent être connectés à l'[ordinateur](../general/computer.md) avant qu'il ne puisse plus fonctionner. De plus, elle fournit des fonctionnalités graphiques de base. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/arrowKeys.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/arrowKeys.md index 1c272ae924..1911ffd3fc 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/arrowKeys.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/arrowKeys.md @@ -1,5 +1,5 @@ # Touches directionnelles -![Heureusement que ce n'est pas fait avec de vraies flèches...](oredict:oc:materialArrowKey) +![Heureusement que ce n'est pas fait avec de vraies flèches...](oredict:opencomputers:materialArrowKey) Au risque de me répéter : c'est la crise des touches. Parce que l'économie des touches a connu une sérieuse inflation ces dernières années. Elles sont utilisées pour fabriquer des [claviers](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/batteryUpgrade1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/batteryUpgrade1.md index ac291754bb..dc51781a6a 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/batteryUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/batteryUpgrade1.md @@ -1,5 +1,5 @@ # Amélioration de batterie -![Made of Metal.](oredict:oc:batteryUpgrade1) +![Made of Metal.](oredict:opencomputers:batteryUpgrade1) Cette amélioration augmente la quantité maximale d'énergie stockée par les appareils, comme les [robots](../block/robot.md) et les [tablettes](tablet.md), ce qui leur permet de fonctionner plus longtemps sans devoir revenir vers un [chargeur](../block/charger.md). Les améliorations de batterie de niveau supérieur peuvent stocker plus d'énergie. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/buttonGroup.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/buttonGroup.md index 87d5208f4e..a3f9049dd0 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/buttonGroup.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/buttonGroup.md @@ -1,5 +1,5 @@ # Groupe de boutons -![Avec Biactol...](oredict:oc:materialButtonGroup) +![Avec Biactol...](oredict:opencomputers:materialButtonGroup) Parce que vous avez *toujours* plein de boutons qui trainent quelque part. Ne mentez pas. Nous avons tous à faire un Maj-clic sur ce bouton de recette, encore et encore. Les groupes de boutons sont utilisés pour fabriquer des [claviers](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/card.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/card.md index 27550f6da1..2b3894aec7 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/card.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/card.md @@ -1,5 +1,5 @@ # Base de carte -![Ne peut pas être lue.](oredict:oc:materialCard) +![Ne peut pas être lue.](oredict:opencomputers:materialCard) C'est un matériau communément utilisé pour fabriquer des cartes dans OpenComputers (comme les [cartes graphiques](graphicsCard1.md), les [cartes réseau](lanCard.md), etc.). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/cardContainer1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/cardContainer1.md index ae60a4532f..007b110add 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/cardContainer1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/cardContainer1.md @@ -1,5 +1,5 @@ # Conteneur de carte -![il peu avwar dé cart !](oredict:oc:cardContainer1) +![il peu avwar dé cart !](oredict:opencomputers:cardContainer1) Le conteneur de carte est une amélioration de conteneur pour que des cartes puissent être insérées ou retirées d'un [robot](../block/robot.md) à la volée. Le niveau maximum de la carte que l'emplacement peut contenir est égal au niveau du conteneur. Contrairement aux amélioration classiques, la complexité des conteneurs est de deux fois leur niveau. Regardez [par là](../block/robot.md) pour avoir des détails sur la complexité des robots. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/chamelium.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/chamelium.md index 4c3e4b214a..d6a4b76730 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/chamelium.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/chamelium.md @@ -1,6 +1,6 @@ # Chamélium -![Ca vient de caméléon, si vous vous demandiez.](oredict:oc:chamelium) +![Ca vient de caméléon, si vous vous demandiez.](oredict:opencomputers:chamelium) Le chamélium est un matériau métamorphe qui est utilisé pour créer des [impressions 3D](../block/print.md) dans une [imprimante 3D](../block/printer.md). De lui même, il n'a aucune utilité, mais est très pratique pour créer des zones simples et entièrement monochromes. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/chip1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/chip1.md index 5f6a89e2e4..9229704abf 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/chip1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/chip1.md @@ -1,5 +1,5 @@ # Puce électronique -![Pas celles qui se mangent.](oredict:oc:circuitChip1) +![Pas celles qui se mangent.](oredict:opencomputers:circuitChip1) Les puces électroniques sont le pain quotidien de la fabrication de composants électroniques. Elles existent en différents niveaux, pour fabriquer différents niveaux de composants. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/chunkloaderUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/chunkloaderUpgrade.md index f7acaaac48..9816731f3a 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/chunkloaderUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/chunkloaderUpgrade.md @@ -1,6 +1,6 @@ # Amélioration chargement de chunk -![Je ne vais nulle part.](oredict:oc:chunkloaderUpgrade) +![Je ne vais nulle part.](oredict:opencomputers:chunkloaderUpgrade) L'amélioration de chargement de chunk peut être installée sur des appareils (comme les [robots](../block/robot.md) et les [microcontrôleurs](../block/microcontroller.md)) pour leur permettre de garder le chunk dans lequel ils sont - ainsi que les chunks environnants - chargés. Cela consomme de l'énergie, cependant. Le chargeur de chunks peut être activé et désactivé par l'API du composant exposé à l'appareil. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/circuitBoard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/circuitBoard.md index e6657ab101..7cf16a1f8e 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/circuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/circuitBoard.md @@ -1,5 +1,5 @@ # Plaque de circuit imprimé -![Il faut plus d'or.](oredict:oc:materialCircuitBoard) +![Il faut plus d'or.](oredict:opencomputers:materialCircuitBoard) C'est un objet intermédiaire fait à partir de [plaques de circuit imprimé brutes](rawCircuitBoard.md) et utilisé pour fabriquer des [circuits imprimés](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/componentBus1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/componentBus1.md index 7a61997a07..f2cf2634cf 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/componentBus1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/componentBus1.md @@ -1,6 +1,6 @@ # Bus des composants -![Plus de P-P-P-PUISSANCE.](oredict:oc:componentBus1) +![Plus de P-P-P-PUISSANCE.](oredict:opencomputers:componentBus1) Un bus des composants est une amélioration dédiée aux [serveurs](server1.md) qui permet à un [serveur](server1.md) de communiquer avec plus de composants à la fois, sans s'éteindre. Comme avec les [processeurs](cpu1.md), un bus de plus haut niveau augmente la limite des composants. Les [serveurs](server1.md) de plus haut niveau sont également capables d'accepter plus de bus de composants, ce qui permet de communiquer avec encore plus de composants. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/controlUnit.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/controlUnit.md index 8a90625280..0ca45d940d 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/controlUnit.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/controlUnit.md @@ -1,5 +1,5 @@ # Unité de contrôle -![Avec régulateur de vitesse intégré.](oredict:oc:materialCU) +![Avec régulateur de vitesse intégré.](oredict:opencomputers:materialCU) Un objet de fabrication de haut niveau utilisé dans des circuits avancés, comme les [processeurs](cpu1.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/cpu1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/cpu1.md index dfcab698a0..eec640073c 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/cpu1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/cpu1.md @@ -1,6 +1,6 @@ # Processeur -![Cerveaaauuu...](oredict:oc:cpu1) +![Cerveaaauuu...](oredict:opencomputers:cpu1) L'unité centrale de traitement (ou *central processing unit (CPU)* en anglais) est un composant essentiel à chaque [ordinateur](../general/computer.md) ou [serveur](server1.md). Il définit l'architecture de l'[ordinateur](../general/computer.md), et le nombre de composants qui peuvent être connectés à l'[ordinateur](../general/computer.md) avant qu'il ne cesse de fonctionner. Un processeur de plus haut niveau permet également d'avoir plus d'appels par tick à l'[ordinateur](../general/computer.md) - en d'autres termes : plus le processeur est puissant, plus il est rapide. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/craftingUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/craftingUpgrade.md index 8c0420354c..22a4d0daa9 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/craftingUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/craftingUpgrade.md @@ -1,5 +1,5 @@ # Amélioration d'artisanat -![C'est en forgeant...](oredict:oc:craftingUpgrade) +![C'est en forgeant...](oredict:opencomputers:craftingUpgrade) L'amélioration d'artisanat permet aux [robots](../item/inventoryUpgrade.md) de réaliser des recettes avec et sans forme en utilisant leur [inventaire](../item/inventoryUpgrade.md). Pour fabriquer, la grille de 3x3 en haut à gauche de l'[inventaire](../item/inventoryUpgrade.md) du [robot](../block/robot.md) est utilisée comme grille de fabrication. Les objets doivent être arrangés selon la recette. Les résultats seront replacés dans l'[inventaire](../item/inventoryUpgrade.md) du [robot](../block/robot.md). Comme pour les objets ramassés par terre, le résultat sera placé dans l'emplacement sélectionné; s'il n'y arrive pas, l'objet sera placé dans l'emplacement vide suivant. S'il n'y a plus de place libre, le résultat sera lâché par terre. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/cuttingWire.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/cuttingWire.md index d5aa5385ea..7e70cbe7e6 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/cuttingWire.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/cuttingWire.md @@ -1,5 +1,5 @@ # Fil de coupe -![Ce n'est pas un garrot. Je le jure.](oredict:oc:materialCuttingWire) +![Ce n'est pas un garrot. Je le jure.](oredict:opencomputers:materialCuttingWire) Un objet qui n'existe que si vous utilisez les recettes difficiles, il est utilisé pour fabriquer des [plaques de circuit imprimé brutes](rawCircuitBoard.md). Très inefficacement. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/dataCard1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/dataCard1.md index 422df92d9d..9bacb6ad9a 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/dataCard1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/dataCard1.md @@ -1,6 +1,6 @@ # Carte de données -![Contrairement à la croyance populaire, elle ne stocke pas de données.](oredict:oc:dataCard1) +![Contrairement à la croyance populaire, elle ne stocke pas de données.](oredict:opencomputers:dataCard1) La carte de données est une carte utilitaire qui fournit quelques algorithmes qui seraient soit compliqués à implémenter sur une architecture, soit lent à l'exécution. Elle fournit des fonctionnalités de hachage, ainsi que des fonctionnalités d'inflation/déflation. De plus, elle contient un système de fichiers qui fournit un certain nombre de programmes en utilisant les fonctionnalités de la carte, comme la carte internet. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/databaseUpgrade1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/databaseUpgrade1.md index 64b34c2e8e..fc58ed5928 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/databaseUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/databaseUpgrade1.md @@ -1,6 +1,6 @@ # Amélioration de base de données -![Je suis dans la matrice!](oredict:oc:databaseUpgrade1) +![Je suis dans la matrice!](oredict:opencomputers:databaseUpgrade1) L'amélioration de base de données peut être configurée pour stocker une liste de représentations de groupes d'objets, qui peuvent ensuite être utilisés par d'autres composants. C'est particulièrement utile pour les objets qui sont uniquement distinguables par leurs données NBT, ce qui ne fait pas partie des données affichées de base pour un groupe d'objets. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/debugCard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/debugCard.md index 092dfc1e93..9fc2084468 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/debugCard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/debugCard.md @@ -1,6 +1,6 @@ # Carte de débogueur -![Attends, si je... oooooh.](item:OpenComputers:item@73) +![Attends, si je... oooooh.](item:opencomputers:debugcard) La carte de débogueur est un objet à usage créatif seulement, qui a été créé à l'origine pour rendre le débogage plus facile, en automatisant certains processus. Depuis, elle a obtenu beaucoup d'autres fonctionnalités, ce qui la rend très utile pour la création de cartes personnalisées. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/disk.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/disk.md index 57f96b5bfa..5eec5867ee 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/disk.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/disk.md @@ -1,5 +1,5 @@ # Disque -![Monde. RIP Terry Pratchett.](oredict:oc:materialDisk) +![Monde. RIP Terry Pratchett.](oredict:opencomputers:materialDisk) Un composant de fabrication de base, utilisé pour fabriquer des moyens de stockage de données, comme des [disquettes](floppy.md) et des [disques durs](hdd1.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/drone.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/drone.md index b917b54fbc..0953a7a15e 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/drone.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/drone.md @@ -1,5 +1,5 @@ # Drone -![Big brother essaye de vous regarder.](item:OpenComputers:item@84) +![Big brother essaye de vous regarder.](item:opencomputers:drone) Les drones sont faits en mettant un [boîtier de drone](droneCase1.md) dans un [assembleur](../block/assembler.md). Ce sont des [robots](../block/robot.md) sous forme d'entité, moins chers mais avec moins de fonctionnalités. Ils sont également capables de se déplacer différemment et beaucoup plus vite que les [robots](../block/robot.md), et ils sont généralement controlés en utilisant un programme client sur un [ordinateur](../general/computer.md). Le drone devra avoir une [EEPROM](eeprom.md) configurée pour écouter les commandes entrantes à exécuter, ou pour agir de lui même. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/droneCase1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/droneCase1.md index 08b8b686fe..eacfaf5fe0 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/droneCase1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/droneCase1.md @@ -1,6 +1,6 @@ # Boitier de drone -![Le vol du bourdon.](oredict:oc:droneCase1) +![Le vol du bourdon.](oredict:opencomputers:droneCase1) Le boitier de drone est utilisé pour construire des [drones](drone.md) dans l'[assembler](../block/assembler.md). Les [drones](drone.md) sont des machines légères, rapides et très mobiles avec des fonctionnalités réduites (moins d'améliorations et d'emplacements de composant disponibles). Contrairement aux [robots](../block/robot.md), ils ne peuvent pas utiliser d'outils, et peuvent seulement interagir avec le monde de manière relativement limitée. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/eeprom.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/eeprom.md index 678207bf74..61550d9bde 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/eeprom.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/eeprom.md @@ -1,6 +1,6 @@ # EEPROM -![Let's get this party started.](oredict:oc:eeprom) +![Let's get this party started.](oredict:opencomputers:eeprom) L'EEPROM est ce qui contient le code utilisé pour initialiser un ordinateur quand il démarre. Les données sont stockées dans un tableau d'octets, et peuvent avoir différentes significations pour différentes architectures de [processeur](cpu1.md). Par exemple, pour Lua, c'est généralement un petit script qui recherche les systèmes de fichier avec un script d'initialisation, pour d'autres architectures ça pourrait être du code machine. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/experienceUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/experienceUpgrade.md index 3ae09f216d..73614b348e 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/experienceUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/experienceUpgrade.md @@ -1,6 +1,6 @@ # Amélioration d'expérience -![Ca n'a aucun sens, mais c'est cool.](oredict:oc:experienceUpgrade) +![Ca n'a aucun sens, mais c'est cool.](oredict:opencomputers:experienceUpgrade) L'amélioration d'expérience est une amélioration très spéciale, puisqu'elle permet aux [robots](../block/robot.md) et aux [drones](drone.md) pour collecter l'expérience en accomplissant de nombreuses actions, comme de casser des blocs de minerai ou de tuer des entités. Une simple amélioration peut stocker jusqu'à 30 niveaux, en fournissant un bonus passif par niveau d'expérience, comme de plus grandes vitesses de récolte et une capacité d'énergie accrue. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/floppy.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/floppy.md index 0e6c7aa256..b83d6a0316 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/floppy.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/floppy.md @@ -1,5 +1,5 @@ # Disquette -![Plusieurs pouces.](oredict:oc:floppy) +![Plusieurs pouces.](oredict:opencomputers:floppy) La disquette est le moyen de stockage de données le moins cher et le plus petit dans OpenComputers. C'est une manière très pratique de stocker des données et de les transférer entre les [ordinateurs](../general/computer.md) et les [robots](../block/robot.md) dès le début de la partie. Vous pourrez également trouver des disquettes avec des programmes utiles dans des coffres de donjons (le gestionnaire de paquets Open Programs est un bon exemple, ce qui permet d'installer facilement des programmes à partir d'un dépôt GitHub central). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/generatorUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/generatorUpgrade.md index 40750c39c5..a1714e8185 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/generatorUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/generatorUpgrade.md @@ -1,6 +1,6 @@ # Amélioration de générateur -![Generator X.](oredict:oc:generatorUpgrade) +![Generator X.](oredict:opencomputers:generatorUpgrade) L'amélioration de générateur permet aux appareils de se recharcher à la volée. Pour le moment elle supporte seulement les carburants solides, comme le charbon. Elle a un inventaire interne qui peut stocker un groupe plein de carburant. Le carburant en surplus peut être retiré du générateur en utilisant la méthode appropriée de l'API du composant. En retirant une amélioration du générateur d'un [robot](../block/robot.md), son contenu sera lâché par terre. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/graphicsCard1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/graphicsCard1.md index 014d083140..9d5641f830 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/graphicsCard1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/graphicsCard1.md @@ -1,6 +1,6 @@ # Carte graphique -![Images fantaisie.](oredict:oc:graphicsCard1) +![Images fantaisie.](oredict:opencomputers:graphicsCard1) La carte graphique est un composant essentiel pour la plupart des [ordinateurs](../general/computer.md), elle leur permet d'afficher du texte sur un [écran](../block/screen1.md) qui leur est connecté. La carte graphique a plusieurs niveaux, et comme les [écrans](../block/screen1.md), elle supporte différentes résolutions et profondeurs de couleur. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/hdd1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/hdd1.md index 5580dd8b3b..6c6edc9e49 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/hdd1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/hdd1.md @@ -1,5 +1,5 @@ # Disque dur -![Spaaaace.](oredict:oc:hdd1) +![Spaaaace.](oredict:opencomputers:hdd1) Le disque dur est un moyen de stockage de données de haut niveau dans OpenComputers. Tous les moyens de stockage de données fonctionnent à la même vitesse ; un moyen de stockage de plus haut niveau fournit juste plus d'espace. Il y a également quelques appareils qui peuvent seulement utiliser les disques durs (bien que les serveurs pourraient utiliser un [lecteur de disquettes](../block/diskDrive.md) externe, par exemple). Les disques durs peuvent être placés dans un [raid](../block/raid.md), ce qui permet à plusieurs disques de partager le même système de fichiers. Remarquez que placer un disque dur dans un [raid](../block/raid.md) efface le contenu du disque. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverBoots.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverBoots.md index c6be248c72..9acaa25da2 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverBoots.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverBoots.md @@ -1,6 +1,6 @@ # Bottes de vol plané -![Si vous attrapez un poulet, et que vous sautez...](oredict:oc:hoverBoots) +![Si vous attrapez un poulet, et que vous sautez...](oredict:opencomputers:hoverBoots) Si vous ne voulez pas vous embêter à programmer un [drone](drone.md), voici un usage alternatif : un tremplin ! Ou de glorieux patins à roulettes. Un truc du genre. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverUpgrade1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverUpgrade1.md index 0ae92f3f69..6133141cba 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/hoverUpgrade1.md @@ -1,6 +1,6 @@ # Amélioration de vol plané -![Flotter comme une plume.](oredict:oc:hoverUpgrade1) +![Flotter comme une plume.](oredict:opencomputers:hoverUpgrade1) L'amélioration de vol plané permet aux [robots](../block/robot.md) de voler beaucoup plus au dessus du sol que ce qu'ils pourraient le faire normalement. Contrairement aux [drones](drone.md), ils sont limités par défaut à une hauteur de vol de 8 blocs. Ca n'est généralement pas un problème, parce qu'ils peuvent tout de même monter aux murs. Leurs règles de déplacement peuvent être résumées ainsi : - Les robots peuvent seulement bouger si la position de départ ou d'arrivée est valide (par exemple pour un pont). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/inkCartridge.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/inkCartridge.md index 6a8b603c19..8162b64f38 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/inkCartridge.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/inkCartridge.md @@ -1,5 +1,5 @@ # Cartouche d'encre -![Les couleurs de l'arc-en-ciel.](oredict:oc:inkCartridge) +![Les couleurs de l'arc-en-ciel.](oredict:opencomputers:inkCartridge) Les cartouches d'encre sont faites pour recharger le tampon encreur des [imprimantes 3D](../block/printer.md). Même s'il est possible de les recharger directement avec les pigments, c'est désordonné et inefficace. Il est vivement recommandé d'investir dans une véritable cartouche d'encre OpenComputers (TM), dès aujourd'hui ! (Annonce : elles pourraient coûter plus cher que l'imprimante elle-même, ou pas). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/internetCard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/internetCard.md index 0f8f415fb2..fe084bcc38 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/internetCard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/internetCard.md @@ -1,6 +1,6 @@ # Carte internet -![Vidéos de chat dans 3, 2, ...](oredict:oc:internetCard) +![Vidéos de chat dans 3, 2, ...](oredict:opencomputers:internetCard) La carte internet donne accès à Internet aux [ordinateurs](../general/computer.md). Elle permet d'exécuter de simples requêtes HTTP, et aussi d'ouvrir des sockets client TCP dans lesquels vous pouvez lire et écrire. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/interweb.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/interweb.md index aae00aad14..0f88875d09 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/interweb.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/interweb.md @@ -1,5 +1,5 @@ # Interweb -![Un site sur la toile est un endroit où il y a des toiles. D'araignée.](oredict:oc:materialInterweb) +![Un site sur la toile est un endroit où il y a des toiles. D'araignée.](oredict:opencomputers:materialInterweb) L'interweb est un composant de base pour tout ce qui est lié à des communications à longue distance. Il utilise les mécaniques bizarres de tous les trucs liés au Néant pour permettre la communication via des tunnels quantiques. Il est utilisé notamment pour les [cartes internet](internetCard.md) et les [cartes liées](linkedCard.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryControllerUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryControllerUpgrade.md index d872e38942..fbabc489cd 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryControllerUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryControllerUpgrade.md @@ -1,6 +1,6 @@ # Amélioration du contrôleur d'inventaire -![J'ai le contrôle.](oredict:oc:inventoryControllerUpgrade) +![J'ai le contrôle.](oredict:opencomputers:inventoryControllerUpgrade) L'amélioration du contrôleur d'inventaire donne aux [robots](../block/robot.md) et aux [drones](drone.md) des capacités d'interactions étendues avec les inventaires. Elle permet à un appareil de viser spécifiquement un emplacement dans un inventaire externe quand il lâche ou ramasse un objet. Elle permet également à un appareil de lire des informations détaillées à propos d'un objet. Enfin, elle fournit aux [robots](../block/robot.md) un moyen de changer leur outil équipé sans aide extérieure. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryUpgrade.md index c1b94d3e2e..ca3c5aea26 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/inventoryUpgrade.md @@ -1,6 +1,6 @@ # Amélioration d'inventaire -![Mais où est-ce qu'elle met tout ça...](oredict:oc:inventoryUpgrade) +![Mais où est-ce qu'elle met tout ça...](oredict:opencomputers:inventoryUpgrade) L'amélioration d'inventaire fournit des emplacements d'inventaire supplémentaires pour les [robots](../block/robot.md) et les [drones](drone.md). Pour chaque amélioration d'inventaire, un [robot](../block/robot.md) gagnera 16 emplacements d'inventaire supplémentaires, pour un maximum de 64 emplacements au total ; un [drone](drone.md) gagnera 4 emplacements par amélioration, pour un total de 8 emplacements. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/lanCard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/lanCard.md index 5a7fc0794a..faafb5c06f 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/lanCard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/lanCard.md @@ -1,5 +1,5 @@ # Carte réseau -![Entre dans le réseau.](oredict:oc:lanCard) +![Entre dans le réseau.](oredict:opencomputers:lanCard) La carte réseau permet aux [ordinateurs](../general/computer.md) d'envoyer et de recevoir des messages réseau. Les messages (ou paquets) peuvent être diffusés à tous les noeuds de réception dans un sous-réseau, ou envoyés à un noeud spécifique avec une certaine adresse. Un [relai](../block/relay.md) peut être utilisé pour relier plusieurs sous-réseaux pour relayer des messages entre les sous-réseaux auxquels il est connecté. Il est également possible d'envoyer un message ciblé si le receveur est dans un autre sous-réseau, et si les réseaux sont connectés par un ou plusieurs [relais](../block/relay.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/leashUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/leashUpgrade.md index bf9b22a91a..52c87d60b4 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/leashUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/leashUpgrade.md @@ -1,5 +1,5 @@ # Amélioration de laisse -![-censuré- ~ Vexatos 2015](oredict:oc:leashUpgrade) +![-censuré- ~ Vexatos 2015](oredict:opencomputers:leashUpgrade) L'amélioration de laisse permet de mettre les animaux en laisse, attachés à l'entité contenue dans l'appareil qui héberge le composant, par exemple un [drone](drone.md). En utilisant cette amélioration, plusieurs animaux peuvent être attachés en même temps, ce qui la rend assez utile pour déplacer des troupeaux. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/linkedCard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/linkedCard.md index 4095d496c4..0ccf61c6b6 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/linkedCard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/linkedCard.md @@ -1,5 +1,5 @@ # Carte liée -![Je sens une connexion entre nous.](oredict:oc:linkedCard) +![Je sens une connexion entre nous.](oredict:opencomputers:linkedCard) La carte liée est une version spécialisée et avancée de la [carte réseau](lanCard.md). Elle peut seulement fonctionner par paires, en fournissant une communication en point à point entre les cartes appairées. Les cartes liées peuvent communiquer sur de longues (illimité) distances, et même à travers les dimensions. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/manual.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/manual.md index bba03165f5..71c156926a 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/manual.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/manual.md @@ -1,6 +1,6 @@ # Manuel -![Une bonne lecture.](oredict:oc:manual) +![Une bonne lecture.](oredict:opencomputers:manual) Ce que vous êtes en train de lire en ce moment même ! Le manuel contient une mine d'informations à propos d'OpenComputers (et sûrement plus). Si vous avez besoin d'information sur un objet ou un bloc, ne cherchez pas plus loin ! Descendez pour apprendre comment l'utiliser (avec la souris ou la barre d'ascenseur sur la droite). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/microcontrollerCase1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/microcontrollerCase1.md index 438f776f09..fdf45d35b7 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/microcontrollerCase1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/microcontrollerCase1.md @@ -1,6 +1,6 @@ # Boitier de microcontrôleur -![Qu'il est mignon !](oredict:oc:microcontrollerCase1) +![Qu'il est mignon !](oredict:opencomputers:microcontrollerCase1) Le boitier de microcontrôleur est la base de construction des [microcontrôleurs](../block/microcontroller.md) grâce à l'[assembleur](../block/assembler.md). Les [microcontrôleurs](../block/microcontroller.md) sont des [ordinateurs](../general/computer.md) très primitifs. Ils peuvent seulement contenir une quantité très limitée de composants, et sont faits pour être avoir une utilisation très spécifique, comme la transformation de signaux de redstone, ou le traitement de messages réseaux. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/nanomachines.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/nanomachines.md index e283b9792d..4ad8e3e860 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/nanomachines.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/nanomachines.md @@ -1,6 +1,6 @@ # Nanomachines -![Nanomachines, son.](oredict:oc:nanomachines) +![Nanomachines, son.](oredict:opencomputers:nanomachines) Ces petits bonhommes créent une interface avec votre système nerveux pour vous faire aller toujours plus loin, toujours plus haut, toujours plus fort ! Ou vous tuer. Parfois les deux en même temps ! En clair, les nanomachines fournissent un système basé sur de l'énergie pour appliquer des effets (bons ou mauvais) sur le joueur dans lequel elles résident. Pour "installer" des nanomachines, mangez les ! diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/navigationUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/navigationUpgrade.md index eb13c10b99..c4195fa4e5 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/navigationUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/navigationUpgrade.md @@ -1,6 +1,6 @@ # Amélioration de navigation -![Je suis perdu. Encore.](oredict:oc:navigationUpgrade) +![Je suis perdu. Encore.](oredict:opencomputers:navigationUpgrade) L'amélioration de navigation fournit des informations de localisation et d'orientation aux appareils sur lesquels elle est installée. Les coordonnées que l'amélioration fournit sont relatives au centre de la carte qui a été utilisée pour fabriquer l'amélioration, et la portée fonctionnelle est basée sur la taille de la carte. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/numPad.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/numPad.md index 3112bfeb2d..32f3c24c86 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/numPad.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/numPad.md @@ -1,5 +1,5 @@ # Pavé numérique -![Vérifiez les empreintes, Jackson.](oredict:oc:materialNumPad) +![Vérifiez les empreintes, Jackson.](oredict:opencomputers:materialNumPad) Le pavé numérique est une partie de chaque [clavier](../block/keyboard.md). Il vous permet de saisir des nombres. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/pistonUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/pistonUpgrade.md index b4945e9f96..572aa83be2 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/pistonUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/pistonUpgrade.md @@ -1,6 +1,6 @@ # Amélioration de piston -![Push it.](oredict:oc:pistonUpgrade) +![Push it.](oredict:opencomputers:pistonUpgrade) L'amélioration de piston permet à certains appareils de se comporter comme un piston de base. Une fois installée, un composant avec une seule méthode, `push()`, devient disponible. Si elle est appelée, l'appareil essayera de pousser le bloc qui lui fait face. Pour les [robots](../block/robot.md) et les [microcontrôleurs](../block/microcontroller.md), c'est la face avant; pour les [tablettes](tablet.md), elle utilisera la face avant du joueur. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/printedCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/printedCircuitBoard.md index 03d035dceb..157d727b2a 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/printedCircuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/printedCircuitBoard.md @@ -1,5 +1,5 @@ # Circuit imprimé -![Il ne sort pas d'une imprimante.](oredict:oc:materialCircuitBoardPrinted) +![Il ne sort pas d'une imprimante.](oredict:opencomputers:materialCircuitBoardPrinted) Le circuit imprimé est, avec le [transistor](transistor.md), l'un des matériaux les plus basiques d'OpenComputers. Il est utilisé en tant que base pour beaucoup de composants, comme les [bases de carte](card.md) et un grand nombre de [blocs](../block/index.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/ram1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/ram1.md index 5dad065207..4752f69b17 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/ram1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/ram1.md @@ -1,6 +1,6 @@ # Mémoire -![Do you remember, dancing in September~](oredict:oc:ram1) +![Do you remember, dancing in September~](oredict:opencomputers:ram1) La mémoire est, au même titre que le [processeur](cpu1.md), un composant essentiel à chaque [ordinateur](../general/computer.md). En fonction de l'architecture du [processeur](cpu1.md), la mémoire a un effet important sur ce que l'[ordinateur](../general/computer.md) peut ou ne peut pas faire. Pour l'architecture Lua standard, par exemple, elle contrôle la quantité réelle de mémoire que les scripts Lua peuvent utiliser. Cela signifie que pour exécuter des programmes demandant plus de ressources, vous aurez besoin de plus de mémoire. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/rawCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/rawCircuitBoard.md index dc64cebe8b..efcc446f38 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/rawCircuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/rawCircuitBoard.md @@ -1,5 +1,5 @@ # Plaque de circuit imprimé brute -![Mais elle est très gentille, en fait.](oredict:oc:materialCircuitBoardRaw) +![Mais elle est très gentille, en fait.](oredict:opencomputers:materialCircuitBoardRaw) C'est un matériau de fabrication intermédiaire, utilisé pour fabriquer des [plaques de circuit imprimé](circuitBoard.md) (ou des [circuits imprimés](printedCircuitBoard.md), en fonction de l'ensemble de recettes utilisé). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/redstoneCard1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/redstoneCard1.md index 5f818f81b5..04b8f1d641 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/redstoneCard1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/redstoneCard1.md @@ -1,6 +1,6 @@ # Carte de Redstone -![Voir rouge.](oredict:oc:redstoneCard1) +![Voir rouge.](oredict:opencomputers:redstoneCard1) La carte de redstone permet aux [ordinateurs](../general/computer.md) de lire et émettre des signaux de redstone analogiques dans les blocs adjacents. Quand la force d'un signal entrant change, un signal est injecté dans l'[ordinateur](../general/computer.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/server1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/server1.md index e2b9e9100b..ccb737b181 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/server1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/server1.md @@ -1,6 +1,6 @@ # Serveur -![Ca te servira de leçon.](oredict:oc:server1) +![Ca te servira de leçon.](oredict:opencomputers:server1) Les serveurs sont une sorte d'[ordinateur](../general/computer.md) de haut niveau. Ils peuvent être configurés en les tenant en main et en les utilisant en même temps - comme pour ouvrir un sac à dos ou une Bourse du Néant (d'EnderStorage), par exemple. Après avoir inséré un [processeur](cpu1.md), de la [mémoire](ram1.md) et des cartes d'extension, le serveur doit être placé dans un [support de serveur](../block/serverRack.md). Pour plus d'informations, allez voir l'entrée sur le [support de serveur](../block/serverRack.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/signUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/signUpgrade.md index b886cb3259..930bc45632 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/signUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/signUpgrade.md @@ -1,5 +1,5 @@ # Amélioration de panneau d'E/S -![Je vois les signes sur le mur.](oredict:oc:signUpgrade) +![Je vois les signes sur le mur.](oredict:opencomputers:signUpgrade) Cette amélioration permet d'interagir avec les panneaux dans le monde. Elle permet de lire le message actuel sur le panneau, ainsi que de changer le message sur le panneau (si c'est autorisé). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/solarGeneratorUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/solarGeneratorUpgrade.md index 63d691f623..d5d2858b47 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/solarGeneratorUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/solarGeneratorUpgrade.md @@ -1,6 +1,6 @@ # Amélioration du générateur solaire -![Walking on the sun.](oredict:oc:solarGeneratorUpgrade) +![Walking on the sun.](oredict:opencomputers:solarGeneratorUpgrade) L'amélioration du générateur solaire peut être installée sur des appareils comme les [robots](../block/robot.md), les [drones](drone.md) et les [tablettes](tablet.md) pour générer passivement de l'énergie. Elle fonctionnera seulement si l'appareil est directement exposé à la lumière du soleil ; un appareil dans un endroit fermé ou une zone affectée par la météo ne génèrera pas d'énergie. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tablet.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tablet.md index e200eb873c..646f36923f 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tablet.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tablet.md @@ -1,6 +1,6 @@ # Tablette -![Touche moi si tu peux.](item:OpenComputers:item@68) +![Touche moi si tu peux.](item:opencomputers:tablet) Les tablettes sont faites en mettant un [boîtier de tablette](tabletCase1.md) dans un [assembleur](../block/assembler.md), en le configurant comme vous le voulez et en assemblant. Les tablettes se comportent comme des ordinateurs portables qui ne peuvent pas interagir directement avec le monde - par exemple, les [cartes de redstone](redstoneCard1.md) de base ne fonctionnent pas avec une tablette. Cependant, un certain nombre d'améliorations fonctionne, comme l'[amélioration de panneau d'E/S](signUpgrade.md) ou l'[amélioration de piston](pistonUpgrade.md). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tabletCase1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tabletCase1.md index bba691e488..1b2e5e0bd3 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tabletCase1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tabletCase1.md @@ -1,6 +1,6 @@ # Boitier de tablette -![Il ne se plie pas.](oredict:oc:tabletCase1) +![Il ne se plie pas.](oredict:opencomputers:tabletCase1) Le boitier de tablette est la base de construction des [tablettes](tablet.md), grâce à l'[assembleur](../block/assembler.md). Les [tablettes](tablet.md) sont des [ordinateurs](../general/computer.md) portables très compacts. Elles peuvent accueillir un petit nombre d'améliorations, mais ne peuvent pas interagir avec le monde de la même manière qu'un [boitier d'ordinateur](../block/case1.md) (ce n'est pas aussi simple qu'avec une [carte réseau](lanCard.md) ou une [carte redstone](redstoneCard1.md) par exemple). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankControllerUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankControllerUpgrade.md index 6e115a0b24..076b8359dd 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankControllerUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankControllerUpgrade.md @@ -1,6 +1,6 @@ # Amélioration du contrôleur de réservoir -![Routage liquide.](oredict:oc:tankControllerUpgrade) +![Routage liquide.](oredict:opencomputers:tankControllerUpgrade) L'amélioration du contrôleur de réservoir est aux réservoirs de fluides ce que l'[amélioration de contrôleur d'inventaire](inventoryControllerUpgrade.md) est aux inventaires. Elle permet aux appareils d'obtenir plus d'informations sur les réservoirs internes et adjacents. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankUpgrade.md index 5af40ea890..af37cf6908 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tankUpgrade.md @@ -1,5 +1,5 @@ # Amélioration de réservoir -![Je suis un écureuil.](oredict:oc:tankUpgrade) +![Je suis un écureuil.](oredict:opencomputers:tankUpgrade) L'amélioration de réservoir permet aux appareils de stocker des liquides. Chaque réservoir peut contenir un seul type de liquide, et fournit un volume de 16 seaux (16000mB). Les [robots](../block/robot.md) et les [drones](drone.md) peuvent aspirer des liquides dans le monde et à partir d'autres réservoirs, et peuvent remplir les réservoirs externes, et si le liquide le supporte, ils peuvent également en placer dans le monde. Il n'y a pas de limite au nombre de réservoirs qui peuvent être installés sur un appareil. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/terminal.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/terminal.md index 8dc7db009f..a006484469 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/terminal.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/terminal.md @@ -1,6 +1,6 @@ # Terminal à distance -![Accès à distance.](oredict:oc:terminal) +![Accès à distance.](oredict:opencomputers:terminal) Le terminal à distance peut être utilisé pour contrôler à distance des [serveurs](server1.md). Pour l'utiliser, faites un clic droit en étant accroupi sur un serveur installé dans un [support de serveur](../block/serverRack.md) (cliquez sur le bloc du [support de serveur](../block/serverRack.md), en visant le [serveur](server1.md) pour y lier le terminal). diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/texturePicker.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/texturePicker.md index 0c1e341e1b..b6e9b87a1c 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/texturePicker.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/texturePicker.md @@ -1,6 +1,6 @@ # Ramasseur de texture -![Comment ça, c'est juste une re-texturation ?](oredict:oc:texturePicker) +![Comment ça, c'est juste une re-texturation ?](oredict:opencomputers:texturePicker) Le ramasseur de texture est très utile pour réaliser des modèles pour votre [imprimante 3D](../block/printer.md). Il vous permet de récupérer le nom de la texture utilisé par un bloc, simplement en l'utilisant (et en étant éventuellement accroupi) sur le bloc. Avertissement : pour les blocs qui utilisent un rendu spécial, comme les coffres, cela peut ne pas marcher. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tractorBeamUpgrade.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tractorBeamUpgrade.md index c82cea939f..939ad46422 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/tractorBeamUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/tractorBeamUpgrade.md @@ -1,5 +1,5 @@ # Amélioration du rayon tracteur -![Beam me up, Scotty !](oredict:oc:tractorBeamUpgrade) +![Beam me up, Scotty !](oredict:opencomputers:tractorBeamUpgrade) L'amélioration du rayon tracteur permet aux appareils de ramasser des objets dans un rayon de 3 blocs autour d'eux. Cela peut être très utile quand vous vous servez de [robots](../block/robot.md) dans un ferme à bois ou à quoi que ce soit d'autre, ou quand vous leur faites utiliser des outils qui cassent plusieurs blocs autour d'eux (comme les outils de Tinker's Construct). Chaque opération essayera d'aspirer une pile d'objets à portée, et consommera un peu d'énergie. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/transistor.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/transistor.md index 859c9d50d4..5da62abd92 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/transistor.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/transistor.md @@ -1,5 +1,5 @@ # Transistor -![Désolé, les blagues ne pas disponibles. Si vous souhaitez laisser un message, faites le 1.](oredict:oc:materialTransistor) +![Désolé, les blagues ne pas disponibles. Si vous souhaitez laisser un message, faites le 1.](oredict:opencomputers:materialTransistor) Le transistor est l'un des ingrédients pour la fabrication les plus basiques d'OpenComputers. Il est principalement utilisé pour fabriquer des [puces électroniques](chip1.md) et d'autres bidules électroniques. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/upgradeContainer1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/upgradeContainer1.md index 91ab378dc9..5bbdcb2719 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/upgradeContainer1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/upgradeContainer1.md @@ -1,5 +1,5 @@ # Amélioration de conteneur -![il peu avwar dé améliorassion !](oredict:oc:upgradeContainer1) +![il peu avwar dé améliorassion !](oredict:opencomputers:upgradeContainer1) L'amélioration de conteneur est une amélioration d'espace pour les [robots](../block/robot.md), qui fournit un emplacement dans les [robots](../block/robot.md) terminés dans lequel des améliorations classiques peuvent être insérées. Le niveau maximal des améliorations que cet emplacement peut contenir est égal au niveau du conteneur. Contrairement aux améliorations classiques, la complexité du conteneur est de deux fois son niveau. Allez voir la page des [robots](../block/robot.md) et de l'[assembleur](../block/assembler.md) pour plus d'informations sur la complexité. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/wlanCard1.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/wlanCard1.md index e6f6eefeea..ee041925bd 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/wlanCard1.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/wlanCard1.md @@ -1,6 +1,6 @@ # Carte de réseau sans-fil -![Peut provoquer le cancer. Ou pas.](oredict:oc:wlanCard2) +![Peut provoquer le cancer. Ou pas.](oredict:opencomputers:wlanCard2) La carte de réseau sans fil est une [carte réseau](lanCard.md) améliorée qui, en plus de gérer les messages réseaux filaires, peut également envoyer et recevoir des messages réseaux sans fil. La force du signal contrôle directement la distance jusqu'à laquelle un message peut être reçu, avec cette force étant égale à la distance en blocs. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/worldSensorCard.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/worldSensorCard.md index d0fd8a6bcb..320b85b247 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/worldSensorCard.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/worldSensorCard.md @@ -1,5 +1,5 @@ # Carte de capteur du monde -![Au mépris du danger... Aller là où aucun homme n'est jamais allé auparavant.](oredict:oc:worldSensorCard) +![Au mépris du danger... Aller là où aucun homme n'est jamais allé auparavant.](oredict:opencomputers:worldSensorCard) La carte de capteur du monde permet de lire les informations atmosphériques ainsi que la gravité des différentes planètes ajoutées par Galacticraft. Cela peut être utile pour les [robots](../block/robot.md) ou les [drones](drone.md) travaillant dans l'espace. diff --git a/src/main/resources/assets/opencomputers/doc/fr_fr/item/wrench.md b/src/main/resources/assets/opencomputers/doc/fr_fr/item/wrench.md index 95b523841a..e4aa05a9c3 100644 --- a/src/main/resources/assets/opencomputers/doc/fr_fr/item/wrench.md +++ b/src/main/resources/assets/opencomputers/doc/fr_fr/item/wrench.md @@ -1,5 +1,5 @@ # Crisseur -![Fait en Suisse.](oredict:oc:wrench) +![Fait en Suisse.](oredict:opencomputers:wrench) Un peu comme n'importe quel autre mod technologique, OpenComputers a sa propre version d'une clé anglaise. En l'occurrence, c'est un hybride entre un tournevis et une clé anglaise, ce qui a l'air d'être incroyablement compliqué à l'usage. Il peut être utilisé pour faire tourner la plupart des blocs, et il est également compatible avec les blocs de la plupart des autres mods qui réagissent aux outils de type clé. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/accessPoint.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/accessPoint.md index 6607601f95..1fea56379b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/accessPoint.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/accessPoint.md @@ -1,6 +1,6 @@ # Точка доступа -![AAA](oredict:oc:accessPoint) +![AAA](oredict:opencomputers:accessPoint) *Этот блок устарел и будет удален в следующих версиях.* Замените его на [ретранслятор](relay.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/adapter.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/adapter.md index 9e45e2a238..4d5d753809 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/adapter.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/adapter.md @@ -1,6 +1,6 @@ # Адаптер -![Теперь на 100% больше всего.](oredict:oc:adapter) +![Теперь на 100% больше всего.](oredict:opencomputers:adapter) Адаптеры позволяют [компьютерам](../general/computer.md) взаимодействовать с блоками Minecraft или из других модов. Поддерживаемые блоки, прилегающие к адаптеру, будут отображаться как компоненты [компьютера](../general/computer.md), подключенного к адаптеру. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/assembler.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/assembler.md index bc6a27b4a7..ff01b0e2d2 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/assembler.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/assembler.md @@ -1,6 +1,6 @@ # Сборщик роботов -![Harder, better, faster, stronger.](oredict:oc:assembler) +![Harder, better, faster, stronger.](oredict:opencomputers:assembler) Сборщик роботов - это продвинутая рабочая станция, позволяющая собирать такие сложные устройства, как [роботы](robot.md), [дроны](../item/drone.md) и [планшеты](../item/tablet.md). Они требуют для сборки большое количество энергии, поэтому рекомендуется использовать их совместно с [конденсатором энергии](capacitor.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/cable.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/cable.md index 3399bdb38a..9664410d50 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/cable.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/cable.md @@ -1,6 +1,6 @@ # Кабель -![Зелень.](oredict:oc:cable) +![Зелень.](oredict:opencomputers:cable) Кабель служит для соединения [компьютеров](../general/computer.md) и машин, которые далеки друг от друга. Если вы используете компактную сборку, где все компоненты касаются друг друга (напрямую или нет, большинство блоков ведут себя как кабели), вам они обычно не понадобятся. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/capacitor.md index 38cd3a6fa7..b73f04f1a1 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/capacitor.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/capacitor.md @@ -1,6 +1,6 @@ # Конденсатор энергии -![Больше 9000.](oredict:oc:capacitor) +![Больше 9000.](oredict:opencomputers:capacitor) Конденсатор хранит энергию, используемую в сети, действуя в качестве буфера энергии, когда это необходимо. В отличие от конвертации энергии других модов во внутреннюю энергию OpenComputers (с помощью [конвертера энергии](powerConverter.md), к примеру), передача энергии внутри одной подсети мгновенна. Наличие энергобуфера полезно в случаях, когда необходимо большое количество энергии, например, для [сборки](assembler.md) или [зарядки](charger.md) [роботов](robot.md) или [дронов](../item/drone.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/case1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/case1.md index 34328b566b..10b34b30b5 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/case1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/case1.md @@ -1,6 +1,6 @@ # Системный блок -![Просто коробка.](oredict:oc:case1) +![Просто коробка.](oredict:opencomputers:case1) Системные блоки бывают 3 различных уровней, различающихся количеством компонентов, которые могут быть в них вставлены. Также есть креативный системный блок. Системные блоки могут быть помещены в [сборщик](assembler.md) для создания [робота](robot.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/chameliumBlock.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/chameliumBlock.md index d630d12432..d6a8e4f586 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/chameliumBlock.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/chameliumBlock.md @@ -1,6 +1,6 @@ # Блок хамелиума -![Такой... чистый.](oredict:oc:chameliumBlock) +![Такой... чистый.](oredict:opencomputers:chameliumBlock) Несколько кусочков [хамелиума](../item/chamelium.md) могут быть объединены для получения одноцветный блок — его можно использовать в качестве декорации. Блоки хамелиума могут быть окрашены в любой из 16 стандартных цветов Minecraft. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/charger.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/charger.md index fd5443d90f..7e9a833371 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/charger.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/charger.md @@ -1,6 +1,6 @@ # Зарядное устройство -![Отлично, давайте сделаем это.](oredict:oc:charger) +![Отлично, давайте сделаем это.](oredict:opencomputers:charger) Зарядное устройство предназначено для зарядки устройств, таких как [роботы](robot.md), [дроны](../item/drone.md) и [планшеты](../item/tablet.md). Зарядное устройство активируется редстоун-сигналом. Скорость заряда зависит от силы редстоун-сигнала: так, при силе 15, скорость заряда будет 100%. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/disassembler.md index 1984b95c79..ed7ed9862b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/disassembler.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/disassembler.md @@ -1,6 +1,6 @@ # Разборщик -![Построй это, снеси это.](oredict:oc:disassembler) +![Построй это, снеси это.](oredict:opencomputers:disassembler) Разборщик используется, чтобы разбирать большинство блоков OpenComputers на исходные компоненты. Это удобно для сборки новых деталей из частей старых и ненужных, а таже для разборки устройств, которые вам больше не нужны или были собраны неправильно (например, [роботы](robot.md) без [операционной системы](../general/openOS.md)). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/diskDrive.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/diskDrive.md index c87b2c411b..31da6f0614 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/diskDrive.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/diskDrive.md @@ -1,6 +1,6 @@ # Дисковод -![Ходим вокруг да около...](oredict:oc:diskDrive) +![Ходим вокруг да около...](oredict:opencomputers:diskDrive) Дисковод может быть использован для чтения [дискет](../item/floppy.md) при работе с подключённым к нему [компьютером](../general/computer.md). Это удобно на начальных этапах, потому что низкоуровневые [системные блоки](case1.md) не имеют встроенного дисковода, а вам нужна будет операционная система для запуска [компьютера](../general/computer.md). Дискета с [OpenOS](../general/openOS.md) может быть создана из пустой [дискеты](../item/floppy.md) и [данного руководства](../item/manual.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/geolyzer.md index cb8197fed2..da25f247fc 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/geolyzer.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/geolyzer.md @@ -1,6 +1,6 @@ # Геоанализатор -![Это камень.](oredict:oc:geolyzer) +![Это камень.](oredict:opencomputers:geolyzer) Геоанализатор используется [компьютерами](../general/computer.md) для сканирования плотностей блоков вокруг него. Это можно использовать для генерации карт местности и показа их на [голографическом проекторе](hologram1.md) или для обнаружения полезных блоков (руды обычно тверже земли и камня). В результаты работы анализатора добавляется некоторое количество шума. Теоретически, можно провести несколько сканирований, чтобы получить более точные результаты. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/hologram1.md index b15b4e2a38..987c940fda 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/hologram1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/hologram1.md @@ -1,6 +1,6 @@ # Голографический проектор -![Это реально? Или это только ваше воображение?](oredict:oc:hologram1) +![Это реально? Или это только ваше воображение?](oredict:opencomputers:hologram1) Голографический проектор отображает трёхмерный массив вокселей, каждый из которых может быть включен или выключен с помощью подключенного [компьютера](../general/computer.md). Проектор второго уровня имеет такое же разрешение, что и у первого уровня, но может окрасить воксели в один из трёх указанных пользователем цветов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/keyboard.md index a733d77cff..2859bc8a49 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/keyboard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/keyboard.md @@ -1,6 +1,6 @@ # Клавиатура -![QWERTY](oredict:oc:keyboard) +![QWERTY](oredict:opencomputers:keyboard) Клавиатура необходима для набора текста на [мониторе](screen1.md), и могут стоять отдельным блоком в мире или быть встроены в такие устройства, как [роботы](robot.md) или [планшеты](../item/tablet.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/motionSensor.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/motionSensor.md index 91a1412f66..0b70f29741 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/motionSensor.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/motionSensor.md @@ -1,6 +1,6 @@ # Датчик движения -![Не двигайся.](oredict:oc:motionSensor) +![Не двигайся.](oredict:opencomputers:motionSensor) Датчик движения позволяет [компьютерам](../general/computer.md) замечать движение живых существ. Если существо двигается быстрее, чем заданный порог чувствительности, то будет подан сигнал в [компьютер](../general/computer.md), соединенный с датчиком движения. Вы можете задать порог срабатывания датчика через API, доступный компьютерам. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/netSplitter.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/netSplitter.md index ae3b43a3db..1ce21141bd 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/netSplitter.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/netSplitter.md @@ -1,6 +1,6 @@ # Сетевой переключатель -![*.net *.split](oredict:oc:netSplitter) +![*.net *.split](oredict:opencomputers:netSplitter) Сетевой переключатель позволяет контролировать соединение между подсетями. В отличие от [ретранслятора](relay.md) или [конвертера энергии](powerConverter.md), позволяет непосредственно соединить подсети, делая при этом доступными все компоненты. Соединение каждой стороны переключается [ключом](../item/wrench.md). При подаче сигнала красного камня все соединения инвертируются. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerConverter.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerConverter.md index c284b3233c..00a120f6f6 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerConverter.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerConverter.md @@ -1,5 +1,5 @@ # Конвертер энергии -![Один из нас? Один из нас!](oredict:oc:powerConverter) +![Один из нас? Один из нас!](oredict:opencomputers:powerConverter) Конвертер энергии - это самый быстрый способ преобразования энергии других модов во внутреннюю энергию OpenComputers. Если вы запустите простой компьютер, вероятно, вам не понадобится конвертер. Если у вас есть большой конденсатор, который разражается только время от времени, вам тоже он может не понадобиться. Однако если вы хотите подвести энергию к [сборщику](assembler.md) или [зарядному устройству](charger.md), хорошей идеей будет подключить их через конвертер, чем напрямую. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerDistributor.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerDistributor.md index 23c2b550cd..4e344d6d7c 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerDistributor.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/powerDistributor.md @@ -1,5 +1,5 @@ # Распределитель энергии -![Энергию в массы.](oredict:oc:powerDistributor) +![Энергию в массы.](oredict:opencomputers:powerDistributor) Распределитель энергии распределяет энергию в хранилищах (таких как [конденсатор](capacitor.md)) между подсетями, что позволяет им обмениваться энергией без подключения компонентов к омьпютерам других подсетей. Это достигается "балансированием" энергии во всех подключенных подсетях, поддерживая одинаковым *относительное* количество энергии в них. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/printer.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/printer.md index 93c423eb60..7dba3c37d7 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/printer.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/printer.md @@ -1,6 +1,6 @@ # 3D принтер -![2D печать - прошлый век.](oredict:oc:printer) +![2D печать - прошлый век.](oredict:opencomputers:printer) 3D принтеры позвляют распечатать любой блок любой формы и текстуры. Для начала работы с 3D принтерами вы должны поместить блок 3D принтера рядом с компьютером. Это предоставит доступ к API компонента `printer3d`, позволяющего создавать и печатать [3D модели](print.md) с использованием предоставленные функции. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/rack.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/rack.md index e0b4be02ce..50de71c993 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/rack.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/rack.md @@ -1,6 +1,6 @@ # Стойка -![Бесплатное жилье.](oredict:oc:rack) +![Бесплатное жилье.](oredict:opencomputers:rack) Стойка может содержать до 4 подключемых устройств, как: [серверы](../item/server1.md), [серверы терминалов](../item/terminalServer.md) и [подключаемые дисководы](../item/diskDriveMountable.md). Соединение между монтируемыми устройствами может быть настроено с помощью интерфейса стойки. В частности, если [серверы](../item/server1.md) содержат компоненты, которые поддерживают работу с сетью, такие как [сетевые карты](../item/lanCard.md), то можно установить стороны сетевых соединений. Такие соединения будут служить только для передачи сетевых сообщений, компоненты через них доступны не будут. Они отличаются более тонкой линией, чем у "основных", которые предоставляют доступ к компонентам. Каждое внутреннее соединение должно быть между монтируемым устройством (или компонентом в нем) и шиной, соединенной со стороной стойки. Для соеднинения вместе нескольких подключаемых устройств подключите их на одну общую шину. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/raid.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/raid.md index cb4fd9dc70..00ff822665 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/raid.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/raid.md @@ -1,6 +1,6 @@ # RAID -![40 человек в 1.](oredict:oc:raid) +![40 человек в 1.](oredict:opencomputers:raid) Блок RAID может содержать 3 [жестких диска](../item/hdd1.md), объединенных в единую файловую систему. Объединённая файловая система имеет размер, равный сумме объемов памяти отдельных [жестких дисков](../item/hdd1.md), и доступна всех [компьютеров](../general/computer.md), подключенных к RAID. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/redstone.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/redstone.md index 73e2ce0c7c..3edc00160c 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/redstone.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/redstone.md @@ -1,6 +1,6 @@ # Красный контроллер -![Привет Ред.](oredict:oc:redstone) +![Привет Ред.](oredict:opencomputers:redstone) Красный контроллер используется для считывания и подачи сигнала красного камня. Он ведет себя как гибрид [плат на красном камне](../item/redstoneCard1.md) 1 и 2 уровней: может работать с обычными аналоговыми сигналами и с многожильными кабелями, но не может считывать и подавать беспроводные сигналы красного камня. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/relay.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/relay.md index 0645ca5229..e7f4b1118f 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/relay.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/relay.md @@ -1,6 +1,6 @@ # Ретранслятор -![Строит мосты.](oredict:oc:relay) +![Строит мосты.](oredict:opencomputers:relay) Ретранслятор используется для передачи сообщений между несколькими подсетями без предоставления компонентов [компьютерам](../general/computer.md) в других подсетях. Как правило, изоляция компонентов - хорошая идея, чтобы не позволить [компьютерам](../general/computer.md) использовать не тот [монитор](screen1.md) или избежать достижения лимита компонентов (в результате чего [компьютеры](../general/computer.md) выключатся и отказываются загружаться). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/screen1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/screen1.md index 7d57166600..39456ae687 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/screen1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/screen1.md @@ -1,6 +1,6 @@ # Монитор -![Вы тоже видите это?](oredict:oc:screen1) +![Вы тоже видите это?](oredict:opencomputers:screen1) Монитор используется совместно с [видеокартой](../item/graphicsCard1.md), чтобы позволить [компьютеру](../general/computer.md) отображатьа текст. Разные уровни мониторов имеют разные возможности, такие как разное разрешение и глубина цвета. Они варьируются от монохромных мониторов низкого разрешения до мониторы высокого разрешения, поддерживающих 256 цветов соответственно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/switch.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/switch.md index 559d2f3ae2..5e3b8ca1ba 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/switch.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/switch.md @@ -1,6 +1,6 @@ # Коммутатор -![Строит мосты.](oredict:oc:switch) +![Строит мосты.](oredict:opencomputers:switch) *Этот блок устарел и будет удален в следующих версиях.* Замените его на [ретранслятор](relay.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/transposer.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/transposer.md index 9ebae6c138..b4e2441175 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/transposer.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/transposer.md @@ -1,6 +1,6 @@ # Транспозер -![Такой позер.](oredict:oc:transposer) +![Такой позер.](oredict:opencomputers:transposer) Транспозер заполняет пробел между воронками, контролируемыми сигналом красного камня, и [роботами](robot.md), позволяя [компьютерам](../general/computer.md) контролировать перемещение предметов и жидкостей между соседними блоками. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/block/waypoint.md b/src/main/resources/assets/opencomputers/doc/ru_ru/block/waypoint.md index 013f7f9057..4bcfa00a3d 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/block/waypoint.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/block/waypoint.md @@ -1,6 +1,6 @@ # Путевая точка -!["Сюда!" - "Нет, туда!"](oredict:oc:waypoint) +!["Сюда!" - "Нет, туда!"](oredict:opencomputers:waypoint) [Навигационное улучшение](../item/navigationUpgrade.md) может обнаруживать путевые точки, что позволяет устройствам с этим улучшением ориентироваться в игровом мире. Это можно использовать для написания программ для [роботов](robot.md) и [дронов](../item/drone.md), которые просто могут быть переиспользованы. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/general/example.md b/src/main/resources/assets/opencomputers/doc/ru_ru/general/example.md index 6804e5b741..dac2b44b6a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/general/example.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/general/example.md @@ -4,13 +4,13 @@ ![Это всплывающее сообщение...](opencomputers:textures/gui/printer_ink.png) ![Это всплывающее сообщение...](opencomputers:/textures/gui/printer_material.png) *Это* текст *курсивом*, ~~зачеркнутый~~, может быть, **немного** текста **жирным**. Это _подчеркнутый текст_? А, нет, _снова курсив!_ Хорошо, вот [ссылка](../index.md). -![Это рендирится напрямую.](oredict:oc:assembler) +![Это рендирится напрямую.](oredict:opencomputers:assembler) ## Заголовок второго уровня [снова со *ссылкой*, но __немного__ длиннее](../block/adapter.md) -![Это еще одно всплывающее сообщение.](item:OpenComputers:item@23) +![Это еще одно всплывающее сообщение.](item:opencomputers:transistor) какой-то текст прямо над изображением для тестирования отступов -![Все цвета.](oredict:craftingPiston) +![Все цвета.](oredict:forge/piston) какой-то текст сразу под изображением для тестирования отступов Это *две @@ -42,9 +42,9 @@ asdasd ![о нет, рекурсия!](img/example.png) qweqwe И наконец, [это ссылка!](https://avatars1.githubusercontent.com/u/514903). -![Поврежденное изображение](item:повреждено) -![Поврежденное изображение](block:повреждено) -![Поврежденное изображение](oredict:повреждено) +![Поврежденное изображение](item:this_is_broken) +![Поврежденное изображение](block:this_is_broken) +![Поврежденное изображение](oredict:this_is_broken) тест переносов 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 @@ -53,17 +53,17 @@ asdasd ![о нет, рекурсия!](img/example.png) qweqwe * 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 - `123456789012345678901234567890.12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890` -Это тест![](oredict:oc:cpu1) картинки в тексте kakakakalalsd 123 as +Это тест![](oredict:opencomputers:cpu1) картинки в тексте kakakakalalsd 123 as -Это один тест![](oredict:oc:cpu1) +Это один тест![](oredict:opencomputers:cpu1) картинки, после которой переход на следующую строку Это один тест -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) изображения между двумя пустыми строками Тест -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) картинками между двумя пустыми строками diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/ru_ru/general/quickstart.md index 949024b1c5..2ff4e8499c 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/general/quickstart.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/general/quickstart.md @@ -6,7 +6,7 @@ Вначале вам понадобится [системный блок](../block/case1.md). Этот блок будет содержать все компоненты, определяющие поведение собираемого компьютера. -![Системный блок второго уровня.](oredict:oc:case2) +![Системный блок второго уровня.](oredict:opencomputers:case2) Например, вам потребуется выбрать, какого уровня [видеокарту](../item/graphicsCard1.md) вы будете использовать, нужна ли вам [сетевая](../item/lanCard.md) карта, [плата на красном камне](../item/redstoneCard1.md) или даже [карта отладки](../item/debugCard.md), если вы играете в творческом режиме. @@ -37,7 +37,7 @@ Он ожил! В любом случае, должен был. Если этого не произошло, значит, что-то пошло не так, и нужно искать ошибку с помощью [анализатора](../item/analyzer.md). Но предпологая, что компьютер заработал, вы почти закончили. Самая сложная часть позади. Теперь осталось заставить его принимать ввод и выводить какой-то результат. Чтобы [компьютер](computer.md) мог выводить информацию, вы должны установить [монитор](../block/screen1.md) и [видеокарту](../item/graphicsCard1.md). -![Нет, это не плоский экран.](oredict:oc:screen2) +![Нет, это не плоский экран.](oredict:opencomputers:screen2) Установите [монитор](../block/screen1.md) рядом с [системным блоком](../block/case1.md) или, опять же, подключите его с помощью [кабеля](../block/cable.md). После чего установите [видеокарту](../item/graphicsCard1.md) по вашему выбору в [системный блок](../block/case1.md). Теперь вы должны увидеть мигающий курсор на [мониторе](../block/screen1.md). Наконец, поставьте [клавиатуру](../block/keyboard.md) перед [монитором](../block/screen1.md) или на одну из его сторон, чтобы получить возможность вводить текст с [клавиатуры](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/abstractBusCard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/abstractBusCard.md index b1cf6f50ca..a924e6e4af 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/abstractBusCard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/abstractBusCard.md @@ -1,5 +1,5 @@ # Карта абстрактной шины -![Нужно больше сетей!](oredict:oc:abstractBusCard) +![Нужно больше сетей!](oredict:opencomputers:abstractBusCard) Карта позволяет [компьютерам](../general/computer.md), [серверам](server1.md) и [роботам](../block/robot.md) взаимодействовать с абстрактной шиной из мода StargateTech2. При установке карты устройства подключаются к абстрактной шине и получают доступ к компонента, который позволяет передавать сообщения через шину. Входящие сообщения шины конвертируются в сигналы, которые получают устройства. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/acid.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/acid.md index 52a2ebf757..d18b613fb8 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/acid.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/acid.md @@ -1,6 +1,6 @@ # Кислота -![Отлив?](oredict:oc:materialAcid) +![Отлив?](oredict:opencomputers:materialAcid) Это вкусное [нет авторитетного источника] варево можно употребить, когда вам когда-либо вдруг захочется немного... веселья. Или пищевого отравления. Или и того и другого. Также может служить ингредиентом в других, более полезных вещах. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/alu.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/alu.md index 82b3ce1769..8d84c5b309 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/alu.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/alu.md @@ -1,5 +1,5 @@ # Арифметико-логическое устройство -![Я могу считать!](oredict:oc:materialALU) +![Я могу считать!](oredict:opencomputers:materialALU) Используется для крафта компонентов, выполняющие вычисления, например, [процессоров](cpu1.md) и [видеокарт](graphicsCard1.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/analyzer.md index bcee402e6c..bc4e41602d 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/analyzer.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/analyzer.md @@ -1,6 +1,6 @@ # Анализатор -![Что же это такое.](oredict:oc:analyzer) +![Что же это такое.](oredict:opencomputers:analyzer) Анализатор - это ручной инструмент, предназначенный для получения информации о блоках OpenComputers. Просто нажмите по блоку (приседая, если требуется), и информация будет выведена в чат. В зависимости от блока вы можете получить от адреса компонента до уровня энергии в подсети, в которой находится блок, и, например, ошибки, приведшей к сбою [компьютера](../general/computer.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/angelUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/angelUpgrade.md index 81eacb3c64..d8ab8444e2 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/angelUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/angelUpgrade.md @@ -1,5 +1,5 @@ # "Ангельское" улучешение -![Аллилуйя](oredict:oc:angelUpgrade) +![Аллилуйя](oredict:opencomputers:angelUpgrade) Данное улучшение позволяет [роботам](../block/robot.md) ставить блоки прямо в воздухе, без соседнего блока. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/apu1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/apu1.md index ee5d488bd2..7cab16580c 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/apu1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/apu1.md @@ -1,6 +1,6 @@ # Процессор с видеокартой (APU) -![Awesomest Probability Unifier.](oredict:oc:apu1) +![Awesomest Probability Unifier.](oredict:opencomputers:apu1) Это результат объединения [процессора](cpu1.md) и [видеокарты](graphicsCard1.md). Позволяет вам освободить один слот для карт в устройстве. Как и обычный процессор, он определяет архитектуру [компьютера](../general/computer.md) и максимальное количество компонентов, которые могут быть подключены к [компьютеру](../general/computer.md). Помимо этого, он предоставляет функции видеокарты. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/arrowKeys.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/arrowKeys.md index bc2f5434c3..33f8de7455 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/arrowKeys.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/arrowKeys.md @@ -1,5 +1,5 @@ # Клавиши со стрелками -![Будьте благодарны, что они делаются не из стрел.](oredict:oc:materialArrowKey) +![Будьте благодарны, что они делаются не из стрел.](oredict:opencomputers:materialArrowKey) Это необходимый элемент для крафта [клавиатуры](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/batteryUpgrade1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/batteryUpgrade1.md index 4d8aef90be..a53368c876 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/batteryUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/batteryUpgrade1.md @@ -1,5 +1,5 @@ # Улучшение "Ёмкость" -![Сделано из металла.](oredict:oc:batteryUpgrade1) +![Сделано из металла.](oredict:opencomputers:batteryUpgrade1) Данное улучшение увеличивает емкость внутреннего энергохранилища, что позволяет [роботам](../block/robot.md) и [планшетам](tablet.md) работать гораздо дольше без [зарядки](../block/charger.md). Чем выше уровень улучешния, тем больше энергии он может хранить. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/buttonGroup.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/buttonGroup.md index 0774888dfc..442053f360 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/buttonGroup.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/buttonGroup.md @@ -1,5 +1,5 @@ # Группа кнопок -![Нужно больше кнопок.](oredict:oc:materialButtonGroup) +![Нужно больше кнопок.](oredict:opencomputers:materialButtonGroup) Необходимый компонент для крафта [клавиатуры](../block/keyboard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/card.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/card.md index d24d9c28dc..7e714e929b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/card.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/card.md @@ -1,5 +1,5 @@ # Карта -![Не может быть считана.](oredict:oc:materialCard) +![Не может быть считана.](oredict:opencomputers:materialCard) Обычный компонент для крафта карт в OpenComputers (например, [видеокарт](graphicsCard1.md), [сетевых карт](lanCard.md) и т. д.). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/cardContainer1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/cardContainer1.md index e3d4afb361..2ac73a976a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/cardContainer1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/cardContainer1.md @@ -1,5 +1,5 @@ # Контейнер для карт -![Может хранить карты!](oredict:oc:cardContainer1) +![Может хранить карты!](oredict:opencomputers:cardContainer1) Контейнер для карт - улучшение-контейнер для [роботов](../block/robot.md), позволящее вставлять и извлекать карты из [роботов](../block/robot.md) без пересборки. Максимальный уровень карты равен уровню контейнера. В отличие от обычных улучшений, требуемая сложность сборки двойная. Подробнее о сложности сборки смотрите [здесь](../block/robot.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/chamelium.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/chamelium.md index f3fcb6d078..fcbb0aa6af 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/chamelium.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/chamelium.md @@ -1,6 +1,6 @@ # Хамелиум -![От слова "хамелеон", на всякий случай.](oredict:oc:chamelium) +![От слова "хамелеон", на всякий случай.](oredict:opencomputers:chamelium) Хамелиум - основной материал, используемый для создания [3D моделей](../block/print.md) на [3D принтерах](../block/printer.md). Сам по себе он однороден, а потому очень полезен для создания простых гладких одноцветных поверхностей. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/chip1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/chip1.md index 9b74bd5493..433547a3c5 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/chip1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/chip1.md @@ -1,5 +1,5 @@ # Микрочипы -![Несъедобные.](oredict:oc:circuitChip1) +![Несъедобные.](oredict:opencomputers:circuitChip1) Микрочипы - основа всех электронных компонентов в OpenComputers. Они имеют различные уровни для крафта компонентов разных уровней. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/chunkloaderUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/chunkloaderUpgrade.md index 37153d017d..b18e991646 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/chunkloaderUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/chunkloaderUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Загрузчик чанков" -![Никуда не денется.](oredict:oc:chunkloaderUpgrade) +![Никуда не денется.](oredict:opencomputers:chunkloaderUpgrade) Это улучшение может быть установлено в устройства (например, в [роботов](../block/robot.md) и [микроконтроллеры](../block/microcontroller.md)), чтобы они могли загружать чанки, в которых они находятся, а также соседние чанки. Однако на это требуется энергия. Загрузчик чанков может быть включен или выключен через API компонента. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/circuitBoard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/circuitBoard.md index 8dd3874677..66a0fc8962 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/circuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/circuitBoard.md @@ -1,5 +1,5 @@ # Нетравленая печатная плата -![Нужно больше золота.](oredict:oc:materialCircuitBoard) +![Нужно больше золота.](oredict:opencomputers:materialCircuitBoard) Промежуточный предмет, сделанный из [основы для печатной платы](rawCircuitBoard.md). Используется для создания [печатной платы](printedCircuitBoard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/componentBus1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/componentBus1.md index d3d38c6d15..9e1eb5e392 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/componentBus1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/componentBus1.md @@ -1,6 +1,6 @@ # Компонентая шина -![Мне нужно боооооольше.](oredict:oc:componentBus1) +![Мне нужно боооооольше.](oredict:opencomputers:componentBus1) Компонентная шина - это [серверное](server1.md) улучшение, которое позволяет подключать к [серверу](server1.md) большее количество компонентов. Как и с [процессорами](cpu1.md), чем выше уровень шины, тем большее число компонентов можно подключить. Кроме того, чем выше уровень [сервера](server1.md), тем больше компонентных шин вы сможете вставить, что позволяет работать с еще большим числом компонентов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/controlUnit.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/controlUnit.md index 46ca8cd031..b0b1cdeffb 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/controlUnit.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/controlUnit.md @@ -1,5 +1,5 @@ # Блок управления -![Теперь со встроенным круиз-контролем.](oredict:oc:materialCU) +![Теперь со встроенным круиз-контролем.](oredict:opencomputers:materialCU) Предмет, используемый при создании более продвинутых схем, например [процессоров](cpu1.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/cpu1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/cpu1.md index 566305e3cc..4d612bfdb3 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/cpu1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/cpu1.md @@ -1,6 +1,6 @@ # Процессор -![Мозги...](oredict:oc:cpu1) +![Мозги...](oredict:opencomputers:cpu1) Основа всех [компьютеров](../general/computer.md) и [серверов](server1.md). Определяет архитектуру [компьютера](../general/computer.md) и максимальное число компонентов, которые могут быть к нему подключены. Чем выше уровень процессора, тем больше [компьютер](../general/computer.md) может вызывать прямых методов в тик - проще говоря, чем лучше процессор, тем быстрее он работает. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/craftingUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/craftingUpgrade.md index c8fcab4001..edb8f1d583 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/craftingUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/craftingUpgrade.md @@ -1,5 +1,5 @@ # Улучшение "Верстак" -![Скрафти это.](oredict:oc:craftingUpgrade) +![Скрафти это.](oredict:opencomputers:craftingUpgrade) Это улучшение позволяет [роботам](../block/robot.md) крафтить предметы с помощью предметов из своего [инвентаря](../item/inventoryUpgrade.md). Для крафта используется сетка слотов 3x3 в левом верхнем углу [инвентаря](../item/inventoryUpgrade.md) [робота](../block/robot.md). Предметы должны быть расположены в соответствии с рецептом. Результаты крафта будут помещены в [инвентарь](../item/inventoryUpgrade.md) [робота](../block/robot.md) — в выбранный слот; если же он заполнен, тогда используется следующий слот. В случае если место в инвентаре закончилось, результаты крафта будут выброшены в мир. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/cuttingWire.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/cuttingWire.md index cb749af497..046220597d 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/cuttingWire.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/cuttingWire.md @@ -1,5 +1,5 @@ # Проволока -![Не гаррота. Честно.](oredict:oc:materialCuttingWire) +![Не гаррота. Честно.](oredict:opencomputers:materialCuttingWire) Если включены сложные рецепты, нужна для создания [основы для печатной платы](rawCircuitBoard.md) - очень неэффективного. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/dataCard1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/dataCard1.md index 5c68b6aec5..2d5c539c22 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/dataCard1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/dataCard1.md @@ -1,6 +1,6 @@ # Карта данных -![Вопреки распространенному поверью, не хранит данные.](oredict:oc:dataCard1) +![Вопреки распространенному поверью, не хранит данные.](oredict:opencomputers:dataCard1) Карта данных предоставляет несколько алгоритмов, которые труднореализуемы или работают медленнее на архитектуре компьютеров, например хэширование и inflate/deflate. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/databaseUpgrade1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/databaseUpgrade1.md index 79a1149633..4ab094448d 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/databaseUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/databaseUpgrade1.md @@ -1,6 +1,6 @@ # Улучшение "База данных" -![Living in the database.](oredict:oc:databaseUpgrade1) +![Living in the database.](oredict:opencomputers:databaseUpgrade1) Улучшение может быть настроено на хранение списка предметов, которые могут быть использованы другими компонентами. Это особенно полезно для элементов, отличающиеся только NBT-данными, которые не возвращаются методами компонентов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/debugCard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/debugCard.md index 11100abfd0..31d6af7079 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/debugCard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/debugCard.md @@ -1,6 +1,6 @@ # Отладочная карта -![Подождите.](item:OpenComputers:item@73) +![Подождите.](item:opencomputers:debugcard) Отладочная карта - это творческий предмет, который изначально был предназначен для упрощения отладки мода за счет автоматизации некоторых процессов. С тех пор она обрела большую функциональность, что делает ее полезным инструментом для создания карт. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/disk.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/disk.md index 6241df1ba8..90bbb20ac8 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/disk.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/disk.md @@ -1,5 +1,5 @@ # Диск -![Discworld. Памяти Терри Пратчетта.](oredict:oc:materialDisk) +![Discworld. Памяти Терри Пратчетта.](oredict:opencomputers:materialDisk) Базовый компонент для создания устройств хранения информации, таких как [дискеты](floppy.md) и [жесткие диски](hdd1.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/diskDriveMountable.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/diskDriveMountable.md index b9bedfd6dc..2624b86a04 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/diskDriveMountable.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/diskDriveMountable.md @@ -1,5 +1,5 @@ # Дисковод для серверной стойки -![Snuggly](oredict:oc:diskDriveMountable) +![Snuggly](oredict:opencomputers:diskDriveMountable) Аналог обычного [дисковода](../block/diskDrive.md), за исключением того, что он установливается в [стойку](../block/rack.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/drone.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/drone.md index 48679a7305..2451397a04 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/drone.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/drone.md @@ -1,5 +1,5 @@ # Дрон -![Большой брат пытается следить за тобой.](item:OpenComputers:item@84) +![Большой брат пытается следить за тобой.](item:opencomputers:drone) Дроны собираются из [корпуса дрона](droneCase1.md) в [сборщике](../block/assembler.md). По сути, они являются [роботами](../block/robot.md) в виде сущностей, но с меньшим функционалом. Они также могут перемещаться по диагонали и гораздо быстрее, чем [роботы](../block/robot.md). Они обычно контролируются с помощью программы на [компьютере](../general/computer.md). Дроны могут быть сконфигурированы с помощью [EEPROM](eeprom.md) для выполнения различных комманд. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/droneCase1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/droneCase1.md index 5c2eaa7e9b..205d25973a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/droneCase1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/droneCase1.md @@ -1,6 +1,6 @@ # Корпус дрона -![Полетели.](oredict:oc:droneCase1) +![Полетели.](oredict:opencomputers:droneCase1) Корпус дрона используется для создания [дронов](drone.md) в [сборщике](../block/assembler.md). [Дроны](drone.md) - легковесные, быстрые и очень мобильные устройства с ограниченной функциональностью (доступно меньше слотов для компонентов и улучешний). В отличие от [роботов](../block/robot.md), они не могут использовать инструменты и взаимодействуют с игровым миром ограниченно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/eeprom.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/eeprom.md index 5401ec2098..912bb35274 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/eeprom.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/eeprom.md @@ -1,6 +1,6 @@ # EEPROM -![Начнем вечеринку.](oredict:oc:eeprom) +![Начнем вечеринку.](oredict:opencomputers:eeprom) EEPROM содержит код, который позволяет загрузить компьютер. Эти данные хранятся в виде простого массива байтов и могут означать разные вещи на [процессорах](cpu1.md) разных архитектур. Например, для Lua это обычно маленький скрипт, который ищет сценарий инициализации в файловой системе, но для других архитектур это может быть сам машинный код. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/experienceUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/experienceUpgrade.md index 86bdcba68e..0a461192ef 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/experienceUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/experienceUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Опыт" -![Почувствуй силу.](oredict:oc:experienceUpgrade) +![Почувствуй силу.](oredict:opencomputers:experienceUpgrade) Данное улучшение особенное, оно позволяет [роботам](../block/robot.md) и [дронам](drone.md) получать опыт за выполнение различных действий, таких как добыча руд и убийство животных. Одно улучшение может хранить до 30 уровней опыта, предоставляя различные бонусы с каждым уровнем, включая увеличение скорости ломания блоков или увеличения энергохранилища. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/floppy.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/floppy.md index 47fec655ff..96a6e234e9 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/floppy.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/floppy.md @@ -1,5 +1,5 @@ # Дискета -![Много дюймов.](oredict:oc:floppy) +![Много дюймов.](oredict:opencomputers:floppy) Дискета - это самое простое и дешевое средство хранения информации в OpenComputers, удобное на начальных этапах для переноса программ между [компьютерами](../general/computer.md) и [роботами](../block/robot.md). Вы также можете найти дискеты с программами в сокровищницах. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/generatorUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/generatorUpgrade.md index f25426218d..774a290ca6 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/generatorUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/generatorUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Генератор" -![Генератор X.](oredict:oc:generatorUpgrade) +![Генератор X.](oredict:opencomputers:generatorUpgrade) Улучшение позволяет устройствам самозаряжаться за счёт твердого топлива, например угля. Внутренний инвентарь генератора может хранить один стак топлива. Топливо может быть убрано из генератора с помощью метода API компонента. Если вынуть генератор из [робота](../block/robot.md), его содержимое выпадает в игровой мир. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/graphicsCard1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/graphicsCard1.md index 16321f466d..494bc42212 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/graphicsCard1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/graphicsCard1.md @@ -1,6 +1,6 @@ # Видеокарта -![Красивые картинки.](oredict:oc:graphicsCard1) +![Красивые картинки.](oredict:opencomputers:graphicsCard1) Видеокарта является неотъемлемой частью большинства [компьютеров](../general/computer.md) и позволяет им выводить изображение на подключенный [монитор](../block/screen1.md). Видеокарты имеют несколько уровней, как и [мониторы](../block/screen1.md), и в зависимости от него поддерживают различные разрешения и глубину цвета. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/hdd1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/hdd1.md index d1696e3da3..45e9f028ae 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/hdd1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/hdd1.md @@ -1,5 +1,5 @@ # Жесткий диск -![Spaaaace.](oredict:oc:hdd1) +![Spaaaace.](oredict:opencomputers:hdd1) Жесткие диски - это продвинутое хранилище информации в OpenComputers. Все виды жестких дисков имеют одинаковую скорость работы, но разную емкость. Некоторые устройства могут использовать только жесткие диски (хотя серверы могут, например, использовать внешний [дисковод](../block/diskDrive.md)). Жесткие диски могут быть объединены в [RAID](../block/raid.md), благодаря чему несколько дисков будут работать как один большой. При объединении жестких дисков в [RAID](../block/raid.md) вся информация на них будет стерта. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverBoots.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverBoots.md index 075ed791d6..8ae7c92d0b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverBoots.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverBoots.md @@ -1,6 +1,6 @@ # Парящие ботинки -![Быстрее, выше, сильнее.](oredict:oc:hoverBoots) +![Быстрее, выше, сильнее.](oredict:opencomputers:hoverBoots) Если не хочется программировать [дронов](drone.md), то их можно использовать как роликовые коньки. Что-то вроде такого. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverUpgrade1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverUpgrade1.md index e3b3491998..044f90bf91 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverUpgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/hoverUpgrade1.md @@ -1,6 +1,6 @@ # Улучшение "Парение" -![Легкое, как перышко.](oredict:oc:hoverUpgrade1) +![Легкое, как перышко.](oredict:opencomputers:hoverUpgrade1) Это улучшение позволяет [роботам](../block/robot.md) летать гораздо выше над землёю, чем обычно. В отличие от [дронов](drone.md), максимальная высота их полета ограничена 8 блоками по умолчанию. Обычно это не доставляет больших проблем, потому что они все также могут двигаться по стенам и просто вверх. Правила их передвижения могут быть сведены к следующему: - Робот будет двигаться при условии, что или стартовая, или конечная точки являются разрешёнными. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/inkCartridge.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/inkCartridge.md index 5e930f44fe..ef5049992a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/inkCartridge.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/inkCartridge.md @@ -1,5 +1,5 @@ # Картридж с чернилами -![Цвета радуги.](oredict:oc:inkCartridge) +![Цвета радуги.](oredict:opencomputers:inkCartridge) Картридж с чернилами используется для цветной печати в [3D принтерах](../block/printer.md). Также можно перезаправить их, используя краски, но это очень неэффективно. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/internetCard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/internetCard.md index 7c690d506e..598ecd71f2 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/internetCard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/internetCard.md @@ -1,5 +1,5 @@ # Интернет карта -![Видео с котиками через 3, 2, ...](oredict:oc:internetCard) +![Видео с котиками через 3, 2, ...](oredict:opencomputers:internetCard) Интернет карта позволяет [компьютерам](../general/computer.md) выходить в интернет. Она позволяет выполнять простые HTTP запросы, а также открывать, читать и писать в TCP сокеты. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/interweb.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/interweb.md index 2b1bac91e9..b77c73dbc6 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/interweb.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/interweb.md @@ -1,5 +1,5 @@ # Интерпаутина -![Вебсайт - это место с паутиной.](oredict:oc:materialInterweb) +![Вебсайт - это место с паутиной.](oredict:opencomputers:materialInterweb) Основной компонент для приборов дальней связи. Интерпаутина использует странную механику, основанную на квантовой передаче сообщений через мир Края. В основном используется при создании [интернет карт](internetCard.md) и [соединенных карт](linkedCard.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryControllerUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryControllerUpgrade.md index f5495bd6cb..200dfb7c2a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryControllerUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryControllerUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Контроллер инвентаря" -![Я контролирую все.](oredict:oc:inventoryControllerUpgrade) +![Я контролирую все.](oredict:opencomputers:inventoryControllerUpgrade) Контроллер инвентаря предоставляет [роботам](../block/robot.md) и [дронам](drone.md) возможность выполнять еще больше действий с инвентарем. Это позволяет устройству явно указывать слоты при перемещении предметов из или во внешний инвентарь, получать подробную информацию о стаках предметов и, наконец, позволяет [роботам](../block/robot.md) самим менять инструмент. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryUpgrade.md index d63e13487c..ba711e7501 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/inventoryUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Инвентарь" -![Где же он хранит все эти вещи?..](oredict:oc:inventoryUpgrade) +![Где же он хранит все эти вещи?..](oredict:opencomputers:inventoryUpgrade) Улучшение позволяет добавить слоты инвентаря для [роботов](../block/robot.md) и [дронов](drone.md). Каждое улучшение дает [роботу](../block/robot.md) 16 дополнительных слотов - до 64 слотов максимум; [дронам](drone.md) даёт 4 слота с каждым апгрейдом - максимально до 8 слотов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/lanCard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/lanCard.md index 7e9cee5fcd..728a12f22e 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/lanCard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/lanCard.md @@ -1,5 +1,5 @@ # Сетевая карта -![Войди в сеть.](oredict:oc:lanCard) +![Войди в сеть.](oredict:opencomputers:lanCard) Сетевая карта позволяет [компьютерам](../general/computer.md) отправлять и получать сетевые сообщения. Сообщения (или пакеты) могут быть отправлены либо всем принимающим устройствам в подсети, либо конкретной сетевой карте с определённым адресом. [Ретрансляторы](../block/relay.md) могут быть использованы для связи нескольких подсетей друг с другом и передачи сообщений. Также возможно отправить письмо получателю в другой подсети, если сети соединены одним или несколькими [ретрансляторами](../block/relay.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/leashUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/leashUpgrade.md index 5fdfd693be..384189818e 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/leashUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/leashUpgrade.md @@ -1,5 +1,5 @@ # Улучшение "Поводок" -![-отредактировано- ~ Vexatos 2015](oredict:oc:leashUpgrade) +![-отредактировано- ~ Vexatos 2015](oredict:opencomputers:leashUpgrade) Позволяет привязывать животных к различным устройствам, например [дронам](drone.md). Одновременно можно привязать несколько животных, что делает это довольно удобным для перемещения стад. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/linkedCard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/linkedCard.md index e52f7545ef..b2b7bf651b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/linkedCard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/linkedCard.md @@ -1,5 +1,5 @@ # Соединенные карты -![Я чувствую, что мы связаны.](oredict:oc:linkedCard) +![Я чувствую, что мы связаны.](oredict:opencomputers:linkedCard) Соединенная карта - это специализированная, но продвинутая версия [сетевой карты](lanCard.md). Они могут работать только в паре, образуя прямое соединение между картами. Соединенные карты могут передавать данные через большие (точнее, бесконечные) расстояния, а также между измерениями. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/manual.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/manual.md index 863f53a9bf..9e3c9ba0a0 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/manual.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/manual.md @@ -1,6 +1,6 @@ # Руководство -![Стоит прочитать.](oredict:oc:manual) +![Стоит прочитать.](oredict:opencomputers:manual) То, что вы сейчас читаете. В руководстве собрана информация об OpenComputers. Если вы хотите что-либо узнать о блоке или предмете из этого мода, это то, что вам нужно! Пролистните вниз с помощью колёсика мыши, чтобы узнать, как пользоваться руководством. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/mfu.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/mfu.md index 4d186fe01c..e90af6d64a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/mfu.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/mfu.md @@ -1,6 +1,6 @@ # МФУ -![Вы никогда не узнаете истинного смысла этой аббревиатуры.](oredict:oc:mfu) +![Вы никогда не узнаете истинного смысла этой аббревиатуры.](oredict:opencomputers:mfu) Это улучшение работает как удаленный [адаптер](../block/adapter.md). Приседая, кликните на любую сторону какого-либо блока, чтобы привязать МФУ к нему. Потом поместите его в адаптер (расстояние очень ограничено), и он будет действовать так, будто адаптер расположен рядом со стороной блока, к которой вы его привязали. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/microcontrollerCase1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/microcontrollerCase1.md index 7003d6414b..7daf4d553b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/microcontrollerCase1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/microcontrollerCase1.md @@ -1,6 +1,6 @@ # Корпус микроконтроллера -![Он такой милый.](oredict:oc:microcontrollerCase1) +![Он такой милый.](oredict:opencomputers:microcontrollerCase1) Корпус микроконтроллера используется для создания [микроконтроллеров](../block/microcontroller.md) в [сборщике](../block/assembler.md). [Микроконтроллеры](../block/microcontroller.md) - это очень примитивные [компьютеры](../general/computer.md). Они содержат только очень ограниченный набор компонентов и используются в специфических задачах: реагирование на сигнал красного камня или обработка сетевых сообщений. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/nanomachines.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/nanomachines.md index 6a4dffe3f5..4a4f7298c2 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/nanomachines.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/nanomachines.md @@ -1,6 +1,6 @@ # Нанороботы -![Нанороботы, Карл.](oredict:oc:nanomachines) +![Нанороботы, Карл.](oredict:opencomputers:nanomachines) Это миниатюрные устройства, которые интегрируются с вашей нервной системой, чтобы сделать вас сильнее, лучше и быстрее или убить вас. Иногда все вместе. Проще говоря, нанороботы предоставляют систему, работающую на энергии и дающие игроку положительными (и отрицательными) эффектами. Съешьте нанороботов, чтобы ввести их в организм. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/navigationUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/navigationUpgrade.md index cf557b5fce..98efaf2110 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/navigationUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/navigationUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Навигация" -![Я потерялся. Снова.](oredict:oc:navigationUpgrade) +![Я потерялся. Снова.](oredict:opencomputers:navigationUpgrade) Данное улучшение предоставляет информацию о местоположении и ориентации устройствам. Получаемые координаты относительны к центру карты, использованной при создании улучшения, а радиус функционирования зависит от размера карты. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/numPad.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/numPad.md index c3e4387d0c..3f74ad7613 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/numPad.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/numPad.md @@ -1,5 +1,5 @@ # Цифровой блок клавиш -![Проверьте на отпечатки пальцев.](oredict:oc:materialNumPad) +![Проверьте на отпечатки пальцев.](oredict:opencomputers:materialNumPad) Цифровая клавиатура - часть любой [клавиатуры](../block/keyboard.md). Позволяет вводить цифры. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/pistonUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/pistonUpgrade.md index 7e53fa66ec..fef1f2050b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/pistonUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/pistonUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Поршень" -![Толкни.](oredict:oc:pistonUpgrade) +![Толкни.](oredict:opencomputers:pistonUpgrade) Улучшение "Поршень" позволяет некоторым устройствам работать так же, как и обычный поршень. После установки станет доступен компонент с одним методом - `push()`. При вызове данного метода устройство попытается сдвинуть блок, находящийся перед ним. Для [роботов](../block/robot.md) и [микроконтроллеров](../block/microcontroller.md) это передняя сторона; для [планшетов](tablet.md) будет использовано направление, куда смотрит игрок. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/printedCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/printedCircuitBoard.md index e6a70c6eea..f3b756afd0 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/printedCircuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/printedCircuitBoard.md @@ -1,5 +1,5 @@ # Печатная плата -![Также известна как PCB](oredict:oc:materialCircuitBoardPrinted) +![Также известна как PCB](oredict:opencomputers:materialCircuitBoardPrinted) Один из самых базовых компонентов крафта в OpenComputers вместе с [транзистором](transistor.md). Используется как основа для множества компонентов: [карт](card.md) и большого количества [блоков](../block/index.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/ram1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/ram1.md index 4333ea6416..1dcc2f568a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/ram1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/ram1.md @@ -1,6 +1,6 @@ # Оперативная память -![Do you remember, dancing in September~](oredict:oc:ram1) +![Do you remember, dancing in September~](oredict:opencomputers:ram1) Память, как и [процессор](cpu1.md), - неотъемлемая часть всех [компьютеров](../general/computer.md). В зависимости от архитектуры [процессора](cpu1.md), именно память отвечает за то, что [компьютеры](../general/computer.md) могут делать, а что нет. Для стандартной архитектуры Lua, например, это позволяет контролировать количество памяти, которое могут использовать Lua-скрипты. Это значит, что для запуска больших и требовательных программ вам потребуется больше памяти. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/rawCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/rawCircuitBoard.md index 79622624e1..58c0b80376 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/rawCircuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/rawCircuitBoard.md @@ -1,5 +1,5 @@ # Основа для печатной платы -![Не суши.](oredict:oc:materialCircuitBoardRaw) +![Не суши.](oredict:opencomputers:materialCircuitBoardRaw) Компонент крафта, использующийся для создания [печатной платы](circuitBoard.md) (или [отпечатанной печатной платы](printedCircuitBoard.md), в зависимости от используемых набора рецептов). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/redstoneCard1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/redstoneCard1.md index 8eeb418aba..4dcd219067 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/redstoneCard1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/redstoneCard1.md @@ -1,6 +1,6 @@ # Плата на красном камне -![Вижу красный.](oredict:oc:redstoneCard1) +![Вижу красный.](oredict:opencomputers:redstoneCard1) Карта на красном камне позволяет [компьютерам](../general/computer.md) считывать и подавать аналоговый сигнал красного камня в прилегающие блоки. Когда сила входящего сигнала изменяется, [компьютер](../general/computer.md) получает соответствующий сигнал. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/server1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/server1.md index 7b3813cccd..35518881f8 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/server1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/server1.md @@ -1,6 +1,6 @@ # Сервер -![Так тебе и надо.](oredict:oc:server1) +![Так тебе и надо.](oredict:opencomputers:server1) Серверы - это форма [компьютеров](../general/computer.md) более высокого уровня. Они могут быть настроены кликом, держа в руке, - как при открытии рюкзака, например, - а также после установки в [стойку](../block/rack.md) и клику (нацелившись на лицевую сторону сервера в [стойке](../block/rack.md)). Для работы сервер должен быть помещен в [стойку](../block/rack.md). Подробнее читайте на странице о [стойке](../block/rack.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/signUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/signUpgrade.md index 99cc364443..02123d4ebb 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/signUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/signUpgrade.md @@ -1,5 +1,5 @@ # Улучшение "Контроллер табличек" -![Я вижу таблички на стенах.](oredict:oc:signUpgrade) +![Я вижу таблички на стенах.](oredict:opencomputers:signUpgrade) Данное улучшение позволяет устройствам взаимодействовать с табличками в мире: читать текст на табличке, а также менять его, если разрешено. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/solarGeneratorUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/solarGeneratorUpgrade.md index 6fdc5f4687..aecbd5d086 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/solarGeneratorUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/solarGeneratorUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Солнечная панель" -![Я на солнышке лежу.](oredict:oc:solarGeneratorUpgrade) +![Я на солнышке лежу.](oredict:opencomputers:solarGeneratorUpgrade) Данное улучшение может быть установлено в такие устройства, как: [роботы](../block/robot.md), [дроны](drone.md), [планшеты](tablet.md) - для пассивной генерации энергии. Генерация энергии происходит только под прямыми лучами солнца и не происходит в дождь или в помещении. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tablet.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tablet.md index 0c6ee06439..39dc35d73b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tablet.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tablet.md @@ -1,6 +1,6 @@ # Планшет -![Дотронься, если сможешь.](item:OpenComputers:item@68) +![Дотронься, если сможешь.](item:opencomputers:tablet) Планшеты можно создать, если поместить [корпус планшета](tabletCase1.md) в [сборщик](../block/assembler.md), добавить компоненты и собрать. Планшеты работают как переносные компьютеры, которые не могут напрямую взаимодействовать с игровым миром: например, простые [платы на красном камне](redstoneCard1.md) не работают с ними. Также не могут с ними работать некоторые улучшения: [контроллер табличек](signUpgrade.md) или [поршень](pistonUpgrade.md), для примера. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tabletCase1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tabletCase1.md index f75bf0ada8..ea4820704c 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tabletCase1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tabletCase1.md @@ -1,6 +1,6 @@ # Корпус планшета -![Не сгибается.](oredict:oc:tabletCase1) +![Не сгибается.](oredict:opencomputers:tabletCase1) Корпус планшета используется для создания [планшетов](tablet.md) в [сборщике](../block/assembler.md). [Планшеты](tablet.md) - миниатюрные и переносимые [компьютеры](../general/computer.md). В них можно установить некоторые улучшения, но они не могут взаимодействовать с игровым миром, как [системный блок](../block/case1.md) (использовать простые [сетевые карты](lanCard.md) или [плату на красном камне](redstoneCard1.md)). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankControllerUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankControllerUpgrade.md index e8f85b1413..050a827e54 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankControllerUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankControllerUpgrade.md @@ -1,6 +1,6 @@ # Улучшение "Контроллер бака" -![Маршрутизация жидкостей.](oredict:oc:tankControllerUpgrade) +![Маршрутизация жидкостей.](oredict:opencomputers:tankControllerUpgrade) Контроллер бака аналогичен [контроллеру инвентаря](inventoryControllerUpgrade.md), но для жидкостей. Позволяет устройствам получать подробную информацию о баках и их содержимом. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankUpgrade.md index 3d12be6303..3e8be279b9 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tankUpgrade.md @@ -1,5 +1,5 @@ # Улучшение "Бак для жидкостей" -![Высоси это.](oredict:oc:tankUpgrade) +![Высоси это.](oredict:opencomputers:tankUpgrade) Позволяет устройствам хранить жидкости. Каждый бак может хранить жидкость только одного типа и объемом не более 16 ведер (16000mB). [Роботы](../block/robot.md) и [дроны](drone.md) могут выкачивать жидкости из игрового мира, а также из других баков. Затем они могут снова заполнять баки жидкостями и обратно выливать их (если жидкость поддерживает выливание в мир). Вы можете установить любое количество улучшений этого вида в устройство. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminal.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminal.md index 9d078bfb72..a904c6aee9 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminal.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminal.md @@ -1,6 +1,6 @@ # Удаленный терминал -![Удаленный доступ.](oredict:oc:terminal) +![Удаленный доступ.](oredict:opencomputers:terminal) Терминал может быть использован для контроля компьютеров через [сервер терминалов](terminalServer.md). Перед использованием кликните по [серверу терминалов](terminalServer.md), установленному в [стойку](../block/rack.md) (кликнув по блоку [стойки](../block/rack.md) в мире, направляя курсор на [сервер терминалов](terminalServer.md)), чтобы привязать терминал к серверу терминалов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminalServer.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminalServer.md index ed65044e2e..73fcf3c81b 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminalServer.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/terminalServer.md @@ -1,5 +1,5 @@ # Сервер терминалов -![Удаленный просмотр](oredict:oc:terminalServer) +![Удаленный просмотр](oredict:opencomputers:terminalServer) Серверы терминалов предоставляют виртуальный [монитор](../block/screen1.md) и [клавиатуру](../block/keyboard.md), которыми можно управлять через [удаленные терминалы](terminal.md). Подробнее читайте на странице о [терминале](terminal.md). Для работы установите сервер терминалов в [стойку](../block/rack.md). diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/texturePicker.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/texturePicker.md index b4531ed3a5..cdc0a66694 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/texturePicker.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/texturePicker.md @@ -1,6 +1,6 @@ # Определитель текстур -![Что это за цвет?](oredict:oc:texturePicker) +![Что это за цвет?](oredict:opencomputers:texturePicker) Данный предмет будет в первую очередь удобен при создании моделей для [3D принтеров](../block/printer.md): он позволяет узнать название текстуры блока, установленного в мире, - достаточно просто кликнуть на него. Обратите внимание, что для блоков с особым рендером, таких как сундуки, это может не сработать. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tractorBeamUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tractorBeamUpgrade.md index 3b4683d8fe..cb23b17cf7 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tractorBeamUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tractorBeamUpgrade.md @@ -1,5 +1,5 @@ # Улучшение "Притягивающий луч" -![Пошли со мной.](oredict:oc:tractorBeamUpgrade) +![Пошли со мной.](oredict:opencomputers:tractorBeamUpgrade) Данное улучшение позволяет устройствам подбирать предметы в радиусе 3 блоков вокруг себя. Это очень удобно использовать для [роботов](../block/robot.md)-фермеров, а также если они используют инструменты, ломающие сразу несколько блоков вокруг себя (как инструменты из Tinker's Construct). Каждая операция пытается подобрать один стак предметов вокруг себя, на что затрачивает некоторое количество энергии. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tradingUpgrade.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tradingUpgrade.md index 3096648992..c77b9d6dbf 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/tradingUpgrade.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/tradingUpgrade.md @@ -1,5 +1,5 @@ # Улучшение "Торговля" -![Эквивалентный обмен](oredict:oc:tradingUpgrade) +![Эквивалентный обмен](oredict:opencomputers:tradingUpgrade) Данное улучшение позволяет организовать автоматическую торговлю с торговцами - например, с жителями. В качестве покупателей могут выступать как [роботы](../block/robot.md), так и [дроны](drone.md). Они могут получать информацию о доступных сделках у продавцов, а также собственно торговать. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/transistor.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/transistor.md index 234cb23f13..e3a6b19b8a 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/transistor.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/transistor.md @@ -1,5 +1,5 @@ # Транзистор -![Кажется, я использовал все отсылки.](oredict:oc:materialTransistor) +![Кажется, я использовал все отсылки.](oredict:opencomputers:materialTransistor) Самый простой элемент крафта в OpenComputers. Он используется для крафта [микрочипов](chip1.md) и иных электронных компонентов. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/upgradeContainer1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/upgradeContainer1.md index 62252b4b63..4c826b9162 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/upgradeContainer1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/upgradeContainer1.md @@ -1,5 +1,5 @@ # Контейнер для улучшения -![Может хранить улучшение.](oredict:oc:upgradeContainer1) +![Может хранить улучшение.](oredict:opencomputers:upgradeContainer1) Это улучшение-контейнер для [роботов](../block/robot.md), добавляющее собранным [роботам](../block/robot.md) слот под установку еще одного улучшения. Максимальный уровень улучшения, которое может быть установлено, равен уровню контейнера. Прочтите документацию о [роботах](../block/robot.md) и [сборщике](../block/assembler.md) для информации о требуемой сложности сборки. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/wlanCard1.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/wlanCard1.md index 7f007d1f88..dcf99fed13 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/wlanCard1.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/wlanCard1.md @@ -1,6 +1,6 @@ # Беспроводная сетевая карта -![Может вызвать рак. Не может.](oredict:oc:wlanCard2) +![Может вызвать рак. Не может.](oredict:opencomputers:wlanCard2) Беспроводная сетевая карта - это улучшенная версия [сетевой карты](lanCard.md), которая в дополнение к сообщениям по проводной линии также может принимать сообщения и по беспроводной сети. Сила сигнала напрямую контролирует, на каком расстоянии может быть получено отправленное сообщение, и равна расстоянию в блоках. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/worldSensorCard.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/worldSensorCard.md index 8bdbbd0160..5c03c3daa2 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/worldSensorCard.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/worldSensorCard.md @@ -1,4 +1,4 @@ # Карта-мировой сенсор -![Для смелых...](oredict:oc:worldSensorCard) +![Для смелых...](oredict:opencomputers:worldSensorCard) Данная карта позволяет получать информацию об атмосфере и гравитации на планетах, добавляемых модом GalactiCraft. Может быть полезно для [роботов](../block/robot.md) и [дронов](drone.md), работающих в космосе. diff --git a/src/main/resources/assets/opencomputers/doc/ru_ru/item/wrench.md b/src/main/resources/assets/opencomputers/doc/ru_ru/item/wrench.md index f5e4910f50..c9d3b9d3c4 100644 --- a/src/main/resources/assets/opencomputers/doc/ru_ru/item/wrench.md +++ b/src/main/resources/assets/opencomputers/doc/ru_ru/item/wrench.md @@ -1,5 +1,5 @@ # Ключ -![Сделано в Швейцарии.](oredict:oc:wrench) +![Сделано в Швейцарии.](oredict:opencomputers:wrench) Как и другие технологические моды, OpenComputers имеет свой ключ. В данном случае это гибрид ключа и отвертки, который выглядит, будто его очень неудобно использовать. Ключ может поворачивать большинство блоков; кроме того, его можно использовать вместо других ключеподобных инструментов. diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/accesspoint.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/accesspoint.md index 968d07ff90..114439f7ea 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/accesspoint.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/accesspoint.md @@ -1,6 +1,6 @@ # 接入点 -![AAA](oredict:oc:accessPoint) +![AAA](oredict:opencomputers:accessPoint) *本方块已废弃,将会在未来版本被移除* 请在工作台中将其合成为[中继器](relay.md)以避免丢失。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/adapter.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/adapter.md index 10625ff252..fe91645d2e 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/adapter.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/adapter.md @@ -1,6 +1,6 @@ # 适配器 -![Now with 100% more everything.](oredict:oc:adapter) +![Now with 100% more everything.](oredict:opencomputers:adapter) 适配器令[电脑](../general/computer.md)能与原版或其他 Mod 的方块交互。支持适配器的方块在连接适配器后,将会在与适配器连接的[电脑](../general/computer.md)上以组件的形式显示出来。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/assembler.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/assembler.md index 3043669fb7..5a2ed46b2c 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/assembler.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/assembler.md @@ -1,6 +1,6 @@ # 装配器 -![更硬,更好,更快,更强。](oredict:oc:assembler) +![更硬,更好,更快,更强。](oredict:opencomputers:assembler) 装配器是个用来制作精密电子设备的高级工作台,像是[机器人](robot.md)、[无人机](../item/drone.md)和[平板](../item/tablet.md)这样的设备都需要在这里制作。组装电子设备的过程需要消耗大量能源,所以在此推荐使用[电容](capacitor.md)保证其能源供应。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/cable.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/cable.md index 5fc4ed909d..69ad2afd44 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/cable.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/cable.md @@ -1,6 +1,6 @@ # 线缆 -![沙拉。](oredict:oc:cable) +![沙拉。](oredict:opencomputers:cable) 用于连接相距甚远的[电脑](../general/computer.md)和设备。如果你的设备群足够紧凑,你大概不需要这玩意。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/capacitor.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/capacitor.md index 20ba42f83a..99380578fe 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/capacitor.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/capacitor.md @@ -1,6 +1,6 @@ # 电容 -![超 9000!](oredict:oc:capacitor) +![超 9000!](oredict:opencomputers:capacitor) 电容存储了计算机网络需要的能源,实际上就是一个以备不时之需的缓存。和使用[能源转换器](powerConverter.md)将转换其他 Mod 的能量到 OpenComputer 使用的电力不一样的是,电容传输电力的过程是瞬时的。这样一个缓存对一些能耗大的任务比较有用,比如[组装](assembler.md)或[充能](charger.md)[机器人](robot.md)和[无人机](../item/drone.md)这样的设备。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/case1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/case1.md index 7d72bf0457..44453df734 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/case1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/case1.md @@ -1,6 +1,6 @@ # 机箱 -![Just in case.](oredict:oc:case1) +![Just in case.](oredict:opencomputers:case1) 机箱有数个型号,决定了能装什么配件。相比于其他配件的等级,机箱还多一个用于创造模式下调试的等级。机箱还用于在[装配器](assembler.md)中组装[机器人](robot.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/chameliumblock.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/chameliumblock.md index 56e5fa6358..084465234d 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/chameliumblock.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/chameliumblock.md @@ -1,6 +1,6 @@ # 变色块 -![So... blank.](oredict:oc:chameliumBlock) +![So... blank.](oredict:opencomputers:chameliumBlock) 几块[变色材料](../item/chamelium.md)合成出装饰用的单色方块。可用染料染成原版的十六种颜色。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/charger.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/charger.md index b939722d9d..b574503cd9 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/charger.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/charger.md @@ -1,6 +1,6 @@ # 充电机 -![All right, let's do this.](oredict:oc:charger) +![All right, let's do this.](oredict:opencomputers:charger) 充电机可为[机器人](robot.md)、[无人机](../item/drone.md)和[平板](../item/tablet.md)这样的设备充能。需要用红石信号激活方能工作。充能速度被红石信号强度决定,信号强度为 15 时它会全速为设备充能。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/disassembler.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/disassembler.md index dad952de5a..51b9be9473 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/disassembler.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/disassembler.md @@ -1,6 +1,6 @@ # 拆解器 -![造了拆,拆了造。](oredict:oc:disassembler) +![造了拆,拆了造。](oredict:opencomputers:disassembler) 拆解器可以将 OpenComputers 中的绝大多数设备拆成零件。常用来回收不需要的或者制造出错的设备,比如忘了装[系统](../general/openOS.md)的[机器人](robot.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/diskdrive.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/diskdrive.md index 5a1111633a..2809745bda 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/diskdrive.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/diskdrive.md @@ -1,6 +1,6 @@ # 软盘驱动器 -![转啊转啊转啊转……](oredict:oc:diskDrive) +![转啊转啊转啊转……](oredict:opencomputers:diskDrive) 软盘驱动器与[电脑](../general/computer.md)连接后就能读[软盘](../item/floppy.md)了。这东西在初期很有用,因为低级别的[机箱](case1.md)没有内建的软盘插槽,但你需要用软盘装系统。[OpenOS](../general/openOS.md) 的安装盘可以通过用空的[软盘](../item/floppy.md) 和[手册](../item/manual.md)在工作台中合成获得。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/geolyzer.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/geolyzer.md index ddc4dddb98..2bac3174f1 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/geolyzer.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/geolyzer.md @@ -1,6 +1,6 @@ # 地质分析仪 -![It rocks.](oredict:oc:geolyzer) +![It rocks.](oredict:opencomputers:geolyzer) 地质分析仪让电脑能扫描其周边的地形,并描述周边的方块硬度分布。其扫描结果可借助[全息投影机](hologram1.md)显示成地图,或用来寻找有价值的方块,因为矿石的硬度往往比石头大。地质分析仪的扫描结果中有些许干扰,理论上可以通过反复扫描来提高精确度。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/hologram1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/hologram1.md index 11d7a95554..8623cdfbdf 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/hologram1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/hologram1.md @@ -1,6 +1,6 @@ # 全息投影机 -![这是真实的生活吗?还是只是幻想?](oredict:oc:hologram1) +![这是真实的生活吗?还是只是幻想?](oredict:opencomputers:hologram1) 全息投影仪是个立体成像显示器,说穿了就是一个可以显示三维图形的显示器,还能被[电脑](../general/computer.md)控制。T2 的全息投影仪和 T1 的相比,分辨率不变,但是支持电脑控制每个像素的颜色。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/keyboard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/keyboard.md index 0b5df63262..8b991073bf 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/keyboard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/keyboard.md @@ -1,6 +1,6 @@ # 键盘 -![QWERTY](oredict:oc:keyboard) +![QWERTY](oredict:opencomputers:keyboard) 键盘自然是用来在[屏幕](screen1.md)上打字的,或者作为输入设备嵌入[机器人](robot.md)和[平板](../item/tablet.md)中。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/motionsensor.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/motionsensor.md index 52a141ace0..aeda23e0a7 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/motionsensor.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/motionsensor.md @@ -1,6 +1,6 @@ # 运动传感器 -![不,要,眨,眼。](oredict:oc:motionSensor) +![不,要,眨,眼。](oredict:opencomputers:motionSensor) 运动传感器允许[电脑](../general/computer.md)探测生物的移动。如果生物的移动速度超过阈值,相连的[电脑](../general/computer.md)就会收到一个信号。阈值可在相连电脑上用其组件 API 调整。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/netsplitter.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/netsplitter.md index db9bce2180..5787fdbee6 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/netsplitter.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/netsplitter.md @@ -1,6 +1,6 @@ # 网络分配器 -![*.net *.split](oredict:oc:netSplitter) +![*.net *.split](oredict:opencomputers:netSplitter) 网络分配器用于控制子网的连接。和[中继器](relay.md)或者[能源转换](powerConverter.md)不一样,网络分配器会与相邻的子网直接连接。每个面上的连接都可以用[螺丝刀扳手](../item/wrench.md)这样的扳手控制。红石信号可令所有连接反转。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerconverter.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerconverter.md index 6f8922b366..8436b394d4 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerconverter.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerconverter.md @@ -1,5 +1,5 @@ # 能量转换器 -![自己人?自己人!](oredict:oc:powerConverter) +![自己人?自己人!](oredict:opencomputers:powerConverter) 能量转换器是让 OpenComputers 使用其他 Mod 能源的最快捷的办法了。如果你只是运行一台电脑,或是一个用不了几次的大电容,你大概不需要造这个。然而如果你想直接驱动[装配机](assembler.md)或者[充电机](charger.md),那你就应该造一台这个了。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerdistributor.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerdistributor.md index 11d8b1310d..2e1a4ac4ab 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerdistributor.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/powerdistributor.md @@ -1,5 +1,5 @@ # 能量分配器 -![Power to the masses.](oredict:oc:powerDistributor) +![Power to the masses.](oredict:opencomputers:powerDistributor) 能量分配器能在不将组件暴露于子网中的前提下,将一个共享能源池(如[电容](capacitor.md))里的能量分配到各个组件上去。它依照负载均衡的原则工作,因此你会发现每个子网的能量供应都“差不多”。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/printer.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/printer.md index ada5c88c7b..d2e1bb2947 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/printer.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/printer.md @@ -1,6 +1,6 @@ # 3D 打印机 -![2D 打印过时了。](oredict:oc:printer) +![2D 打印过时了。](oredict:opencomputers:printer) 3D 打印机允许你在任何方块上用任何纹理打印出你想要的样子。首先你需要在电脑边放一台打印机,这样电脑就能使用 `printer3d` 这个 API,通过这个 API 就能控制打印机打印出[模型](print.md)了。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/rack.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/rack.md index 928c7a6c98..5e57e35785 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/rack.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/rack.md @@ -1,6 +1,6 @@ # 机架 -![免费住房。](oredict:oc:rack) +![免费住房。](oredict:opencomputers:rack) 机架中可以存放四台像是[服务器](../item/server1.md)、[终端服务器](../item/terminalServer.md)和[可挂载磁盘驱动器](../item/diskDriveMountable.md)这样的设备。你可以通过 GUI 来设定机架中设备的连接关系;特别的,如果服务器里面安装了网卡等组件,那么你可以设定这些服务器只暴露网络连接,而不暴露其内部组件。这样的连接在 GUI 中会以一种更细的连接表示,以与允许访问内部设备的普通连接相区分。内部连接只能在设备(或设备中的组件)与总线之间建立;若需连接多个设备,连接到一条总线上即可。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/raid.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/raid.md index efabd666d8..4f582ef222 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/raid.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/raid.md @@ -1,6 +1,6 @@ # Raid -![40 man instance.](oredict:oc:raid) +![40 man instance.](oredict:opencomputers:raid) Raid 磁盘阵列可将三块[硬盘](../item/hdd1.md)组成一个文件系统,组合的文件系统拥有所有硬盘容量之和的大小,并且所有与其相连的电脑都能访问。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/redstone.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/redstone.md index 82ca6084ae..d622e0385c 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/redstone.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/redstone.md @@ -1,6 +1,6 @@ # 红石 I/O 端口 -![Hi Red.](oredict:oc:redstone) +![Hi Red.](oredict:opencomputers:redstone) 红石 I/O 端口可用来远程读取和发射红石信号。它就像是 T1 和 T2 [红石卡](../item/redstoneCard1.md)的合体,可以收发简单的模拟信号及捆绑信号,但是无法收发无线红石信号。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/relay.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/relay.md index 23bbcbe0cd..5ad9b80faf 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/relay.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/relay.md @@ -1,6 +1,6 @@ # 中继器 -![桥接。](oredict:oc:relay) +![桥接。](oredict:opencomputers:relay) 中继器能在不把组件暴露给其他网络的[电脑](../general/computer.md)的前提下,让子网间进行网络通信。把组件限制在本地网络是个好主意,这样就不用担心[电脑](../general/computer.md)接错屏幕,或者电脑因组件过多崩溃并拒绝启动这样的怪事发生了。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/screen1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/screen1.md index b32b23fad4..a6e9aab2c0 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/screen1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/screen1.md @@ -1,6 +1,6 @@ # 显示屏 -![看见没?](oredict:oc:screen1) +![看见没?](oredict:opencomputers:screen1) 显示屏需要和[显卡](../item/graphicsCard1.md)一起使用,这样电脑才能显示文本。不同型号的屏幕能支持的分辨率和色深不尽相同,从低分单色屏到高分 256 色屏都有。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/switch.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/switch.md index d8d8b291da..1ddd71b491 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/switch.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/switch.md @@ -1,6 +1,6 @@ # Switch -![Building bridges.](oredict:oc:switch) +![Building bridges.](oredict:opencomputers:switch) *本方块已废弃,将会在未来版本被移除* 请在工作台中将其合成为[中继器](relay.md)以避免丢失。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/transposer.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/transposer.md index d21ba56f1e..4d317259d1 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/transposer.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/transposer.md @@ -1,6 +1,6 @@ # 转运器 -![Such a poser.](oredict:oc:transposer) +![Such a poser.](oredict:opencomputers:transposer) 转运器连接了红石控制的漏斗和[机器人](robot.md),这样[电脑](../general/computer.md)就能控制物品和流体在相邻方块之间的传输了。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/block/waypoint.md b/src/main/resources/assets/opencomputers/doc/zh_cn/block/waypoint.md index b337317f1d..647a11eeab 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/block/waypoint.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/block/waypoint.md @@ -1,6 +1,6 @@ # 路径点 -![“这边!”“不,那边!”](oredict:oc:waypoint) +![“这边!”“不,那边!”](oredict:opencomputers:waypoint) 路径点重点不在本身,而是如何使用。[导航升级](../item/navigationUpgrade.md)可以探测路径点,因此安装了这种升级的设备就可以通过路径点来导航。这在编写适用于[机器人](robot.md)和[无人机](../item/drone.md)的高度可重用程序时很有用。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/general/example.md b/src/main/resources/assets/opencomputers/doc/zh_cn/general/example.md index 3bdda70bc6..8db963f6c1 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/general/example.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/general/example.md @@ -4,13 +4,13 @@ This is some test text for the subset of Markdown supported by the planned ingam ![This is a tooltip...](opencomputers:textures/gui/printer_ink.png) ![This is a tooltip...](opencomputers:/textures/gui/printer_material.png) *This* is *italic* text, ~~strikethrough~~ maybe abc-ter **some** text **in bold**. Is _this underlined_? Oh, no, _it's also italic!_ Well, this [a link](../index.md). -![This is rendered live.](oredict:oc:assembler) +![This is rendered live.](oredict:opencomputers:assembler) ## Smaller headline [also with *link* but this __one__ longer](../block/adapter.md) -![This is another tooltip.](item:OpenComputers:item@23) +![This is another tooltip.](item:opencomputers:transistor) some text directly above the item stack renderer to test spacing -![All the colors.](oredict:craftingPiston) +![All the colors.](oredict:forge/piston) some text directly below the item stack renderer to test spacing This is *italic @@ -42,9 +42,9 @@ asdasd ![oh my god, the recursion!](img/example.png) qweqwe And finally, [this is a link!](https://avatars1.githubusercontent.com/u/514903). -![broken item image](item:this is broken) -![broken item image](block:this is broken) -![broken item image](oredict:this is broken) +![broken item image](item:this_is_broken) +![broken item image](block:this_is_broken) +![broken item image](oredict:this_is_broken) wrap testing 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 @@ -53,17 +53,17 @@ wrap testing * 12345678901234567890.1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 - `123456789012345678901234567890.12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890` -this is a test for an![](oredict:oc:cpu1)an inline image kakakakalalsd 123 as +this is a test for an![](oredict:opencomputers:cpu1)an inline image kakakakalalsd 123 as -this is a test for an![](oredict:oc:cpu1) +this is a test for an![](oredict:opencomputers:cpu1) an image with a break after it this is a test for an -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) an image between two lines this is a test for an -![](oredict:oc:cpu1) +![](oredict:opencomputers:cpu1) an image between two blank lines diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/general/quickstart.md b/src/main/resources/assets/opencomputers/doc/zh_cn/general/quickstart.md index 4673873740..3b3c5a537d 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/general/quickstart.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/general/quickstart.md @@ -6,7 +6,7 @@ 首先你需要一个[机箱](../block/case1.md)。你所有的电脑配件都要装这里面,它将决定你电脑的行为。 -![一个 T2 机箱](oredict:oc:case2) +![一个 T2 机箱](oredict:opencomputers:case2) 比如你要挑一个适合你的[显卡](../item/graphicsCard1.md),还可能需要一个[网卡](../item/lanCard.md)、一块[红石卡](../item/redstoneCard1.md)、甚至是创造模式下调试时需要的[调试卡](../item/debugCard.md)。 @@ -37,7 +37,7 @@ 好的,它启动了。如果还有什么问题的话,可以使用[分析仪](../item/analyzer.md)排查。不过我们的电脑应该跑起来了。最难的部分已经过去了,剩下就是如何让电脑输出信息,并且让电脑接受输入。 你需要给电脑配[屏幕](../block/screen1.md)和[显卡](../item/graphicsCard1.md)。 -![不是平板屏幕哦](oredict:oc:screen2) +![不是平板屏幕哦](oredict:opencomputers:screen2) [屏幕](../block/screen1.md)可以直接放在机箱一侧,或是通过[线缆](../block/cable.md)相连。[显卡](../item/graphicsCard1.md)自然是要装机箱里。现在你应该能看到[屏幕](../block/screen1.md)上闪烁的光标了。最后,[键盘](../block/keyboard.md)应安装在[屏幕](../block/screen1.md)上,或直接冲着[屏幕](../block/screen1.md)放置。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/abstractbuscard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/abstractbuscard.md index 47e3204e67..c8df1eff3a 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/abstractbuscard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/abstractbuscard.md @@ -1,5 +1,5 @@ # 抽象总线卡 -![更多的网络连接!](oredict:oc:abstractBusCard) +![更多的网络连接!](oredict:opencomputers:abstractBusCard) 这张卡允许[电脑](../general/computer.md)、[服务器](server1.md)和[机器人](../block/robot.md)与 StargateTech2 的抽象类总线交互。当它安装好时,这些方块会连接到抽象类总线,总线上的组件将会对机器可用,且机器可以通过抽象类总线发送信息。传入抽象类总线的信息将会被转换为发送给机器的信号。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/acid.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/acid.md index 3d473e3c21..ddc4c3cf8f 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/acid.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/acid.md @@ -1,6 +1,6 @@ # 酸液 -![Reflux?](oredict:oc:materialAcid) +![Reflux?](oredict:opencomputers:materialAcid) 可口的[来源请求]混合液体,如果你想……找点乐子,或者烧了你的食管,亦或者都想的话,就喝下去吧。同时也是制作多种物品的原料。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/alu.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/alu.md index a48ce9e892..f929a57fa1 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/alu.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/alu.md @@ -1,5 +1,5 @@ # 算术逻辑单元 -![我有逻辑!](oredict:oc:materialALU) +![我有逻辑!](oredict:opencomputers:materialALU) 用来合成 [CPU](cpu1.md) 和[显卡](graphicsCard1.md)这样需要执行计算的元件。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/analyzer.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/analyzer.md index 0b190777c4..36f2c40097 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/analyzer.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/analyzer.md @@ -1,6 +1,6 @@ # 分析仪 -![必须。抵制。不当的。玩笑。](oredict:oc:analyzer) +![必须。抵制。不当的。玩笑。](oredict:opencomputers:analyzer) 一个小巧的,用来探测 OpenComputers 的方块信息的仪器。只要在潜行时右键就可以把方块信息输出到你的聊天栏里。可以导出的信息从设备地址,到子网内的能量水平,再到让电脑宕机的错误信息应有尽有。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/angelupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/angelupgrade.md index 169ad750fe..6465319e29 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/angelupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/angelupgrade.md @@ -1,5 +1,5 @@ # 天使升级 -![哈利路亚!](oredict:oc:angelUpgrade) +![哈利路亚!](oredict:opencomputers:angelUpgrade) 允许[机器人](../block/robot.md)凭空放置方块,而不用靠着别的方块。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/apu1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/apu1.md index b6b3e22a42..b4a3ce3a50 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/apu1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/apu1.md @@ -1,6 +1,6 @@ # APU -![Awesomest Probability Unifier.](oredict:oc:apu1) +![Awesomest Probability Unifier.](oredict:opencomputers:apu1) [CPU](cpu1.md) 和[显卡](graphicsCard1.md)的完美结合,可以为你省下整整一个插槽。和普通的 CPU 一样,它决定了一台[电脑](../general/computer.md)的架构和这台[电脑](../general/computer.md)最多能够支持多少组件。同时,APU 还提供了基本的图形功能。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/arrowkeys.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/arrowkeys.md index 8c27faf93e..20c1eff785 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/arrowkeys.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/arrowkeys.md @@ -1,5 +1,5 @@ # 方向键 -![感谢它们不是箭头做的。(方向键 arrow key,arrow 有箭头的意思)](oredict:oc:materialArrowKey) +![感谢它们不是箭头做的。(方向键 arrow key,arrow 有箭头的意思)](oredict:opencomputers:materialArrowKey) At the risk of repeating myself: it's a button sink. Because the button economy has seen some serious inflation in recent years. 言归正传,方向键自然是制造[键盘](../block/keyboard.md)的配件。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/batteryupgrade1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/batteryupgrade1.md index 95efc25860..20526a821d 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/batteryupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/batteryupgrade1.md @@ -1,5 +1,5 @@ # 电池升级 -![金属打造。](oredict:oc:batteryUpgrade1) +![金属打造。](oredict:opencomputers:batteryUpgrade1) 用于提升[机器人](../block/robot.md)和[平板](tablet.md)等设备的电池容量,提升它们的续航能力。等级越高存得越多。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/buttongroup.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/buttongroup.md index 97b1bfa113..ec109af877 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/buttongroup.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/buttongroup.md @@ -1,5 +1,5 @@ # 按钮组 -![需要更多的按钮。](oredict:oc:materialButtonGroup) +![需要更多的按钮。](oredict:opencomputers:materialButtonGroup) 你总是把按钮弄得到处都是,我们已经不知 Shift 点击那个按钮配方多少次了。言归正传,按钮组用于制造[键盘](../block/keyboard.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/card.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/card.md index 8b2f55d293..6b65664f6b 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/card.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/card.md @@ -1,5 +1,5 @@ # 基板 -![不可读。](oredict:oc:materialCard) +![不可读。](oredict:opencomputers:materialCard) 用于合成 OpenComputers 中诸如[显卡](graphicsCard1.md)、[网卡](lanCard.md)这样的卡状组件的基础材料。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/cardcontainer1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/cardcontainer1.md index 23e4d6dfaf..05f3c3cc9d 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/cardcontainer1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/cardcontainer1.md @@ -1,5 +1,5 @@ # 卡槽 -![Can haz cards!](oredict:oc:cardContainer1) +![Can haz cards!](oredict:opencomputers:cardContainer1) 卡槽是[机器人](../block/robot.md)的物品栏升级之一,安装后机器人就能热插拔卡。卡槽最高只能支持同级别的卡片。卡槽的复杂度是一般组件的两倍。关于复杂度的说明可参考[这里](../block/robot.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/chamelium.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/chamelium.md index 4d0e885016..41306c6b9e 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/chamelium.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/chamelium.md @@ -1,6 +1,6 @@ # 变色材料 -![如果你想知道:这是变色龙(Chameleon)做的。](oredict:oc:chamelium) +![如果你想知道:这是变色龙(Chameleon)做的。](oredict:opencomputers:chamelium) 变色材料是一种可塑材料,用于在 [3D 打印机](../block/printer.md)中打印出[各种东西](../block/print.md)。它本身没什么特性,可以拿来盖单色的墙。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/chip1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/chip1.md index bfb6189c4f..784586defb 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/chip1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/chip1.md @@ -1,5 +1,5 @@ # 微芯片 -![不是吃的。(chip 也可以指薯片这样的东西)](oredict:oc:circuitChip1) +![不是吃的。(chip 也可以指薯片这样的东西)](oredict:opencomputers:circuitChip1) 微芯片是电子配件的重要元件,分若干级别,用于不同级别的配件。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/chunkloaderupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/chunkloaderupgrade.md index 2529933e99..c420728edf 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/chunkloaderupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/chunkloaderupgrade.md @@ -1,6 +1,6 @@ # 区块加载升级 -![哪儿也不去。](oredict:oc:chunkloaderUpgrade) +![哪儿也不去。](oredict:opencomputers:chunkloaderUpgrade) 可以装在像是[机器人](../block/robot.md)和[微控制器](../block/microcontroller.md))的设备上,以保证其所在区块及相邻的区块的加载。这个功能自然是耗电的。可以透过其组件 API 来控制开关。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/circuitboard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/circuitboard.md index b40fbd16a9..4f05abb03b 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/circuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/circuitboard.md @@ -1,5 +1,5 @@ # 电路板 -![需要更多黄金。](oredict:oc:materialCircuitBoard) +![需要更多黄金。](oredict:opencomputers:materialCircuitBoard) 这是从[未加工电路板](rawCircuitBoard.md)到[印刷电路板](printedCircuitBoard.md)的中间体。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/componentbus1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/componentbus1.md index bfb92169c8..d4924d4ba3 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/componentbus1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/componentbus1.md @@ -1,6 +1,6 @@ # 组件总线 -![再——来——一——打——](oredict:oc:componentBus1) +![再——来——一——打——](oredict:opencomputers:componentBus1) 组件总线是[服务器](server1.md)专用的升级,允许[服务器](server1.md)和更多的组件同时通讯。和 CPU 一样,高级的组件总线可以连接更多的组件。更高级的[服务器](server1.md)能连接的组件总线也越多,这样一来服务器能连接的组件也就更多了。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/controlunit.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/controlunit.md index de41b4017f..ae7e327c89 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/controlunit.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/controlunit.md @@ -1,5 +1,5 @@ # 控制单元 -![内置巡航系统。](oredict:oc:materialCU) +![内置巡航系统。](oredict:opencomputers:materialCU) 合成 [CPU](cpu1.md) 等高级电路的元件。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/cpu1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/cpu1.md index 5e24255d1d..2292a284fb 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/cpu1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/cpu1.md @@ -1,6 +1,6 @@ # CPU -![脑——子——](oredict:oc:cpu1) +![脑——子——](oredict:opencomputers:cpu1) 中央处理器是[电脑](../general/computer.md)和[服务器](server1.md)的核心,定义了[电脑](../general/computer.md)的架构,并决定了可连接组件的数量。级别越高,每 tick 可以进行的函数调用越多。一言以蔽之,级别越高跑得越快。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/craftingupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/craftingupgrade.md index 3985ce817f..b46fb09636 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/craftingupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/craftingupgrade.md @@ -1,5 +1,5 @@ # 合成升级 -![Crafty.](oredict:oc:craftingUpgrade) +![Crafty.](oredict:opencomputers:craftingUpgrade) 合成升级能让[机器人](../block/robot.md)在自己的[物品栏](../item/inventoryUpgrade.md)进行各种合成。[机器人](../block/robot.md)左上的 3X3 格子将会用作合成网格,物品需要根据配方来摆放。合成产物会返回机器人物品栏。捡起物品后,首先会尝试放入指定格子中;若失败,则尝试放在下一个空格子里。如果没有格子了,物品会被丢到地上。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/cuttingwire.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/cuttingwire.md index 6acfca8a2a..2e34f40bb8 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/cuttingwire.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/cuttingwire.md @@ -1,5 +1,5 @@ # 切割线 -![真的,不是上吊绳。](oredict:oc:materialCuttingWire) +![真的,不是上吊绳。](oredict:opencomputers:materialCuttingWire) 在困难模式合成中会用到的东西,用于合成[未加工电路板](rawCircuitBoard.md)。很低效。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/databaseupgrade1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/databaseupgrade1.md index d4782483d2..4b26c157e0 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/databaseupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/databaseupgrade1.md @@ -1,6 +1,6 @@ # 数据库升级 -![住在数据库里。](oredict:oc:databaseUpgrade1) +![住在数据库里。](oredict:opencomputers:databaseUpgrade1) 数据库升级可以通过配置来存储一系列物品信息,进而被其他组件所使用。对于仅仅通过 NBT 数据来区分的物品极为有用,因为它们在回调中并不会作为物品描述符的一部分。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/datacard1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/datacard1.md index 19b13c8ddb..ca238588f9 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/datacard1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/datacard1.md @@ -1,6 +1,6 @@ # 数据卡 -![和大众的认知不同,它根本不存数据。](oredict:oc:dataCard1) +![和大众的认知不同,它根本不存数据。](oredict:opencomputers:dataCard1) 数据卡提供了多个难以在架构上实现,或者是在那里跑得很慢的算法,例如散列函数、压缩解压缩等。和网卡一样,数据卡也内嵌有一个文件系统,存有一些需要用到这些功能的程序。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/debugcard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/debugcard.md index 2384a7b259..4170e36bd7 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/debugcard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/debugcard.md @@ -1,6 +1,6 @@ # 调试卡 -![等等,如果…… 哦。](item:OpenComputers:item@73) +![等等,如果…… 哦。](item:opencomputers:debugcard) 调试卡本身是一种仅用于在创造模式下对设备进行快速调试的卡片。有鉴于其丰富的功能,它对于地图制作也很有用处。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/disk.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/disk.md index cf00e955d8..a46dd2435c 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/disk.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/disk.md @@ -1,5 +1,5 @@ # 磁碟 -![这个世界。愿特里·普拉切特安息。(特里·普拉切特的代表作“Discworld”(《碟形世界》)标题亦可理解成“磁碟的世界”)](oredict:oc:materialDisk) +![这个世界。愿特里·普拉切特安息。(特里·普拉切特的代表作“Discworld”(《碟形世界》)标题亦可理解成“磁碟的世界”)](oredict:opencomputers:materialDisk) 用于合成[软盘](floppy.md)和[硬盘](hdd1.md)的基础零件。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/diskdrivemountable.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/diskdrivemountable.md index 6c39cf44a7..0f4c680431 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/diskdrivemountable.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/diskdrivemountable.md @@ -1,5 +1,5 @@ # 可挂载软盘驱动器 -![舒服](oredict:oc:diskDriveMountable) +![舒服](oredict:opencomputers:diskDriveMountable) 这玩意相当于装进[机架](../block/rack.md)里的[软盘驱动器](../block/diskDrive.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/drone.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/drone.md index 7895611cf5..a6697cc7c6 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/drone.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/drone.md @@ -1,5 +1,5 @@ # 无人机 -![老大哥正试图看着你。](item:OpenComputers:item@84) +![老大哥正试图看着你。](item:opencomputers:drone) 无人机需通过在[装配器](../block/assembler.md)中装配[无人机箱](droneCase1.md)制造。他们是实体形态的[机器人](../block/robot.md),造价便宜但功能受限。无人机通常由[电脑](../general/computer.md)程序控制移动,移动速度比[机器人](../block/robot.md)快,而且方向也可以不一样。无人机需要 [EEPROM](eeprom.md) 来监听指令或独自行动。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/dronecase1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/dronecase1.md index 2a4d76d303..9c469627c3 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/dronecase1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/dronecase1.md @@ -1,6 +1,6 @@ # 无人机外壳 -![无人机:嗡嗡嗡,嗡嗡嗡](oredict:oc:droneCase1) +![无人机:嗡嗡嗡,嗡嗡嗡](oredict:opencomputers:droneCase1) 无人机外壳是在[装配机](../block/assembler.md)中组装[无人机](drone.md)时所用的容器。[无人机](drone.md)是种轻量、快速、功能受限(只有少量的升级和插槽)的移动设备。和[机器人](../block/robot.md)不一样,无人机不能使用工具,也只能和世界进行有限的交互。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/eeprom.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/eeprom.md index 06b71ba86a..6e04445bb7 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/eeprom.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/eeprom.md @@ -1,6 +1,6 @@ # EEPROM -![让我们开始吧。](oredict:oc:eeprom) +![让我们开始吧。](oredict:opencomputers:eeprom) EEPROM 中包含了在电脑启动后引导其完成初始化的代码。这些代码以字节数组的形式保存,在不同的 [CPU](cpu1.md) 架构上有不同的含义,比如对于 Lua BIOS 来说这可能是搜索可用文件系统的初始化代码,对于其他设备这可能是机器码。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/experienceupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/experienceupgrade.md index 25154378a0..ab56754703 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/experienceupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/experienceupgrade.md @@ -1,6 +1,6 @@ # 经验升级 -![这根本解释不通,但它酷,这就够了。](oredict:oc:experienceUpgrade) +![这根本解释不通,但它酷,这就够了。](oredict:opencomputers:experienceUpgrade) 经验升级是一种允许[机器人](../block/robot.md)和[无人机](drone.md)通过杀死怪物、挖矿等操作收集经验球的特种升级。每个升级能存储 30 级经验,并且每一级都可以带来诸如挖矿加速、能量缓存提升等加成。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/floppy.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/floppy.md index d90032f590..bfcb59dcbb 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/floppy.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/floppy.md @@ -1,5 +1,5 @@ # 软盘 -![Many inches.](oredict:oc:floppy) +![Many inches.](oredict:opencomputers:floppy) 是 OpenComputers 中最便宜的存储设备,用于游戏初期在[电脑](../general/computer.md)和[机器人](../block/robot.md)间交换数据。你还可以在地牢中找到一些实用程序的安装软盘(比如 OpenPrograms Package Manager,一个能让你轻松从某个 GitHub 仓库中下载并安装程序的包管理器)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/generatorupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/generatorupgrade.md index 818435ef46..7e852cea08 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/generatorupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/generatorupgrade.md @@ -1,6 +1,6 @@ # 发电机升级 -![Generator X.](oredict:oc:generatorUpgrade) +![Generator X.](oredict:opencomputers:generatorUpgrade) 发电机升级是个给设备内嵌发电设备的升级。目前它仅支持煤这样的固体燃料。内部有存储燃料的物品栏。多余燃料可以通过对应的组件 API 取出。从[机器人](../block/robot.md)上移除升级时,会使里面的东西掉出来。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/graphicscard1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/graphicscard1.md index 2820e52c1b..45ac695e8b 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/graphicscard1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/graphicscard1.md @@ -1,6 +1,6 @@ # 显卡 -![炫彩图像](oredict:oc:graphicsCard1) +![炫彩图像](oredict:opencomputers:graphicsCard1) 显卡对大多数计算机都非常重要[computers](../general/computer.md),因为显卡允许[计算机](../general/computer.md)在相连的[屏幕](../block/screen1.md)上显示字符。显卡分若干等级,如同[显示屏](../block/screen1.md)那样支持不同的分辨率和色深。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/hdd1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/hdd1.md index f860229000..d415f8f83c 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/hdd1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/hdd1.md @@ -1,5 +1,5 @@ # 硬盘驱动器 -![空——间!](oredict:oc:hdd1) +![空——间!](oredict:opencomputers:hdd1) 硬盘是 OpenComputers 中的高级存储器,不同等级的硬盘速度一样,只有容量不同,级别越高容量越大。有的设备只能用硬盘存储数据(尽管服务器还可以用外置[软盘驱动器](../block/diskDrive.md))。硬盘还可在 [RAID](../block/raid.md) 中与其他磁盘组成共享文件系统的阵列,不过要注意,硬盘放进 RAID 里的时候之前的数据都会抹除。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverboots.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverboots.md index 8481da65b1..d7240ac6a0 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverboots.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverboots.md @@ -1,6 +1,6 @@ # 悬浮靴 -![一脚油门。](oredict:oc:hoverBoots) +![一脚油门。](oredict:opencomputers:hoverBoots) 如果不想去编程[无人机](drone.md),有个变通的办法:垫脚石!或者说那是美化的内联冰鞋的名字。总之就是这个意思。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverupgrade1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverupgrade1.md index 2195a8bc85..09e62e53b3 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverupgrade1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/hoverupgrade1.md @@ -1,6 +1,6 @@ # 悬浮升级 -![像羽毛一样漂浮。](oredict:oc:hoverUpgrade1) +![像羽毛一样漂浮。](oredict:opencomputers:hoverUpgrade1) 悬浮升级让[机器人](../block/robot.md)飞得更高。默认,机器人只能往上飞 8 格。平常因为机器人能爬墙所以这并不是什么大问题。机器人移动的规律如下: - 机器人只会在起点和终点都有效的情况下才会动(比如允许搭桥)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/inkcartridge.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/inkcartridge.md index 295c90c4ab..39c4b7823b 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/inkcartridge.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/inkcartridge.md @@ -1,5 +1,5 @@ # 墨盒 -![七彩。](oredict:oc:inkCartridge) +![七彩。](oredict:opencomputers:inkCartridge) 墨盒可以很方便地给 [3D 打印机](../block/printer.md)供墨。当然你可以手动用染料来供墨,但这样一不太方便,二没有效率。所以我们强烈建议您今天购买一个真正的 OC 墨盒™!(免责声明:墨盒的价格有可能比打印机还高。) diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/internetcard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/internetcard.md index 17c4d83903..6d1d2da514 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/internetcard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/internetcard.md @@ -1,6 +1,6 @@ # 因特网卡 -![猫片播放倒数,3,2,……](oredict:oc:internetCard) +![猫片播放倒数,3,2,……](oredict:opencomputers:internetCard) 装了这个[电脑](../general/computer.md)就能联网了。它能承载简单的 HTTP 请求以及读写普通的 TCP 客户端套接字。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/interweb.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/interweb.md index cdc12d6f4c..0b94d794dc 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/interweb.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/interweb.md @@ -1,5 +1,5 @@ # 因特网 -![网站就是有蜘蛛网的站点。](oredict:oc:materialInterweb) +![网站就是有蜘蛛网的站点。](oredict:opencomputers:materialInterweb) 因特网是长距离通信设备用到的基本元件,基本原理是利用各种末影物质的奇怪性质以进行某种量子通讯。主要用在[因特网卡](internetCard.md)和[连接卡](linkedCard.md)上。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventorycontrollerupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventorycontrollerupgrade.md index 713aa9d653..94116b68a6 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventorycontrollerupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventorycontrollerupgrade.md @@ -1,6 +1,6 @@ # 物品栏控制器 -![尽在我的控制之中。](oredict:oc:inventoryControllerUpgrade) +![尽在我的控制之中。](oredict:opencomputers:inventoryControllerUpgrade) 物品栏控制器为[机器人](../block/robot.md)和[无人机](drone.md)提供了额外的物品栏交互能力。它允许设备在从外部容器存取物品时指定具体的格子、读取详细的物品信息以及允许[机器人](../block/robot.md) 不借助外力更换自身装备。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventoryupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventoryupgrade.md index 525019802a..4f55ebb99c 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventoryupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/inventoryupgrade.md @@ -1,6 +1,6 @@ # 物品栏升级 -![它把物品存哪去了……](oredict:oc:inventoryUpgrade) +![它把物品存哪去了……](oredict:opencomputers:inventoryUpgrade) 物品栏升级让[机器人](../block/robot.md)和[无人机](drone.md)有了物品栏。每个升级可为[机器人](../block/robot.md)提供 16 个格子,最大扩展到 64;对于[无人机](drone.md)则是提供 4 个格子,最大扩展到 8。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/lancard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/lancard.md index ba691c1389..5647d3f173 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/lancard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/lancard.md @@ -1,5 +1,5 @@ # 网卡 -![联网。](oredict:oc:lanCard) +![联网。](oredict:opencomputers:lanCard) 网卡允许[电脑](../general/computer.md)在本地网络内收发消息。消息(或者叫封包)可向子网广播,或者是发送至特定地址上的设备。[中继器](../block/relay.md)可以用来桥接不同的子网,使之互相通信。若两个网络间有若干[中继器](../block/relay.md),发送跨越网络到指定设备上的数据包也是可能的。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/leashupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/leashupgrade.md index 8637a9e027..eedb3d0147 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/leashupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/leashupgrade.md @@ -1,5 +1,5 @@ # 拴绳升级 -![-redacted- ~ Vexatos 2015](oredict:oc:leashUpgrade) +![-redacted- ~ Vexatos 2015](oredict:opencomputers:leashUpgrade) 拴绳升级允许[无人机](drone.md)这样的设备给动物拴上拴绳,这样一来这些装了该升级的设备就可以一次性拉走一群动物。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/linkedcard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/linkedcard.md index 36fb17a08e..3472550172 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/linkedcard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/linkedcard.md @@ -1,5 +1,5 @@ # 连接卡 -![我觉得我们之间有种微妙的关系。](oredict:oc:linkedCard) +![我觉得我们之间有种微妙的关系。](oredict:opencomputers:linkedCard) 连接卡是特化的高级[网卡](lanCard.md),只能成对使用,用于点对点(P2P)通讯。连接卡可以进行跨维度无限距离的通讯。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/manual.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/manual.md index b5bfeb6d84..c6e916a220 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/manual.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/manual.md @@ -1,6 +1,6 @@ # OpenComputers 手册 -![值得一读。](oredict:oc:manual) +![值得一读。](oredict:opencomputers:manual) 没错就是你正在读的东西!本手册涵盖了 OpenComputers 的所有内容(甚至还有别的东西)。如果你需要关于 OpenComputers 的某个方块或物品的信息,查手册就可以了!用鼠标滚轮往下翻(或者右边的滑块往下拉)来学习如何使用本手册。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/mfu.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/mfu.md index 59ab66c633..6410065ce1 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/mfu.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/mfu.md @@ -1,6 +1,6 @@ # MFU -![你永远也不会知道这个缩写是什么意思。](oredict:oc:mfu) +![你永远也不会知道这个缩写是什么意思。](oredict:opencomputers:mfu) 这个升级相当于远程[适配器](../block/adapter.md)。潜行时,对任意方块的任意面使用该升级以将其与这个面绑定。然后,将其安装到附近的适配器里面(这个“附近”很有限)。好了,现在这个加了 MFU 的适配器就能访问到与 MFU 绑定的方块了! diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/microcontrollercase1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/microcontrollercase1.md index 515cab46ea..72949c6fbe 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/microcontrollercase1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/microcontrollercase1.md @@ -1,6 +1,6 @@ # 微控制器盒 -![超可爱的。](oredict:oc:microcontrollerCase1) +![超可爱的。](oredict:opencomputers:microcontrollerCase1) 微控制器盒是在[装配机](../block/assembler.md)中制造[微控制器](../block/microcontroller.md)的基础。 [微控制器](../block/microcontroller.md)是种极其简化的[电脑](../general/computer.md),只有少量组件,通常设计为特定用途,比如转发或者处理红石信号以及处理网路消息。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/nanomachines.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/nanomachines.md index 9f39d3b8af..d14096eff9 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/nanomachines.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/nanomachines.md @@ -1,6 +1,6 @@ # 纳米机器 -![这是纳米机器,我的儿子。](oredict:oc:nanomachines) +![这是纳米机器,我的儿子。](oredict:opencomputers:nanomachines) 这些跟你的神经系统打交道的玩意能让你变得更快、更高、更强,或者干掉你。甚至有时候这些是同时发生的!简单来说,纳米机器的用途就是往宿主玩家上加 buff 和 debuff。“安装”方法:吃下去! diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/navigationupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/navigationupgrade.md index 3f1d716243..3ae1348fed 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/navigationupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/navigationupgrade.md @@ -1,6 +1,6 @@ # 导航升级 -![我,又,走丢了。](oredict:oc:navigationUpgrade) +![我,又,走丢了。](oredict:opencomputers:navigationUpgrade) 导航升级可提供宿主设备的位置和朝向。坐标是相对用于合成这个升级的地图的中心而言的,它的作用范围也限制在那张地图的大小中。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/numpad.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/numpad.md index 8dc25a6b84..4587ebc09a 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/numpad.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/numpad.md @@ -1,5 +1,5 @@ # 数字键 -![指纹检查。](oredict:oc:materialNumPad) +![指纹检查。](oredict:opencomputers:materialNumPad) 数字键是每块[键盘](../block/keyboard.md)都有的东西,用来输入数字用的。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/pistonupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/pistonupgrade.md index 651c77f519..d21bda0884 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/pistonupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/pistonupgrade.md @@ -1,6 +1,6 @@ # 活塞升级 -![推他。](oredict:oc:pistonUpgrade) +![推他。](oredict:opencomputers:pistonUpgrade) 活塞升级能让某些设备的行为变得像原版活塞那样。安装后会暴露一个只有一个 `push()` 方法的组件。调用此方法时,设备将会试图将它面前的方块推出去。对于[机器人](../block/robot.md)和[单片机](../block/microcontroller.md)来说这就是它们的正面;对于[平板](tablet.md)来说,是玩家视角的那个方向。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/printedcircuitboard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/printedcircuitboard.md index 50167890de..8693313899 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/printedcircuitboard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/printedcircuitboard.md @@ -1,5 +1,5 @@ # 印刷电路板 -![又叫 PCB](oredict:oc:materialCircuitBoardPrinted) +![又叫 PCB](oredict:opencomputers:materialCircuitBoardPrinted) 印刷电路板和[晶体管](transistor.md)一样都是 OpenComputers 中的基础合成材料,用于制作多种元件,例如[卡片](card.md)和为数众多[方块](../block/index.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/ram1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/ram1.md index 78ee629f76..fe839f951e 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/ram1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/ram1.md @@ -1,6 +1,6 @@ # 内存 -![你可曾记得,在九月中起舞~](oredict:oc:ram1) +![你可曾记得,在九月中起舞~](oredict:opencomputers:ram1) 内存和 [CPU](cpu1.md) 一样都是[电脑](../general/computer.md)的核心部件。根据 [CPU](cpu1.md) 的架构的不同,内存很大程度上直接决定了电脑能做什么以及不能做什么。以标准 Lua 架构为例,内存条决定了 Lua 脚本能用多少内存。这意味着你要安装更大的内存条跑更大更复杂的程序。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/rawCircuitBoard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/rawCircuitBoard.md index d0a703fc99..f10836f829 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/rawCircuitBoard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/rawCircuitBoard.md @@ -1,5 +1,5 @@ # 未加工电路板 -![不是寿司。](oredict:oc:materialCircuitBoardRaw) +![不是寿司。](oredict:opencomputers:materialCircuitBoardRaw) 未加工电路板是合成[电路板](circuitBoard.md)及[印刷电路板](printedCircuitBoard.md)的中间材料(以游戏内使用的合成表为准)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/redstonecard1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/redstonecard1.md index e335377a09..18113d9dbb 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/redstonecard1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/redstonecard1.md @@ -1,6 +1,6 @@ # 红石卡 -![红牌。](oredict:oc:redstoneCard1) +![红牌。](oredict:opencomputers:redstoneCard1) 红石卡让[电脑](../general/computer.md)可以收发邻近方块的红石信号。输入信号强度变化时,信号将输入[电脑](../general/computer.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/server1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/server1.md index ae5d83d463..79722f5fdf 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/server1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/server1.md @@ -1,6 +1,6 @@ # 服务器 -![为你服务。](oredict:oc:server1) +![为你服务。](oredict:opencomputers:server1) 服务器是种高级[电脑](../general/computer.md)。你可以通过把它拿在手上像打开背包一样打开来进行配置,也可以放在[机架](../block/rack.md)里面,通过站在机架的正面打开机架操作界面来配置它。详细信息请参见[机架](../block/rack.md)条目。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/signupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/signupgrade.md index e1bcc5a504..b5337b2639 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/signupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/signupgrade.md @@ -1,5 +1,5 @@ # 告示牌 I/O -![我看见墙上的牌子了。](oredict:oc:signUpgrade) +![我看见墙上的牌子了。](oredict:opencomputers:signUpgrade) 这个升级允许设备和告示牌交互,用于读取或改写(如果有权限)告示牌上的信息。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/solargeneratorupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/solargeneratorupgrade.md index 4cea2d8f48..9ae7e3ad7f 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/solargeneratorupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/solargeneratorupgrade.md @@ -1,6 +1,6 @@ # 太阳能发电机升级 -![在太阳上行走。](oredict:oc:solarGeneratorUpgrade) +![在太阳上行走。](oredict:opencomputers:solarGeneratorUpgrade) 太阳能发电机升级可以安装到[机器人](../block/robot.md)、[无人机](drone.md)和[平板](tablet.md)上。它只会在阳光直射的时候工作,不是晴天或者在密闭环境下它是不会产生一丁点能量的。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tablet.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tablet.md index b413fe34f5..d6685a3905 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tablet.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tablet.md @@ -1,6 +1,6 @@ # 平板电脑 -![如果可以,请摸我。](item:OpenComputers:item@68) +![如果可以,请摸我。](item:opencomputers:tablet) 平板电脑是在[装配机](../block/assembler.md)中通过配置[平板外壳](tabletCase1.md)并组装而成的。平板电脑本身是种无法直接与世界交互的移动计算机,比如[基础红石卡](redstoneCard1.md)就不能在平板上用,但像是[告示牌升级](signUpgrade.md)和[活塞升级](pistonUpgrade.md)这样的可以使用。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tabletCase1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tabletCase1.md index 531c05e679..443cb9dad0 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tabletCase1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tabletCase1.md @@ -1,6 +1,6 @@ # 平板电脑外壳 -![不能折弯。](oredict:oc:tabletCase1) +![不能折弯。](oredict:opencomputers:tabletCase1) 平板电脑外壳是在[装配机](../block/assembler.md)中组装[平板电脑](tablet.md)的基础。[平板电脑](tablet.md)是种小型可移动[电脑](../general/computer.md),可加装少量升级,但无法像[机箱](../block/case1.md)那样简单的使用红石卡和网卡和世界交互。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankcontrollerupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankcontrollerupgrade.md index d4c2fced29..627789fadf 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankcontrollerupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankcontrollerupgrade.md @@ -1,6 +1,6 @@ # 储罐控制器 -![流体路由。](oredict:oc:tankControllerUpgrade) +![流体路由。](oredict:opencomputers:tankControllerUpgrade) 储罐控制器可用来控制储罐,用于查询内部储罐和外部的信息。实际上它就是流体版的[物品栏控制器升级](inventoryControllerUpgrade.md)。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankupgrade.md index a9b5bc1920..d98caa5e22 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tankupgrade.md @@ -1,5 +1,5 @@ # 储罐升级 -![Suck it.](oredict:oc:tankUpgrade) +![Suck it.](oredict:opencomputers:tankUpgrade) 储罐升级允许设备存储流体。每个升级仅能存储一种流体,并提供 16 桶容量(即 16000 mB)。[机器人](../block/robot.md)和[无人机](drone.md)可以从世界中和其他储罐汲取液体,也可以倒回世界或者储罐中。单台设备可安装的储罐数没有限制。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminal.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminal.md index 0053efaf1f..68c4499980 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminal.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminal.md @@ -1,6 +1,6 @@ # 终端 -![远程访问。](oredict:oc:terminal) +![远程访问。](oredict:opencomputers:terminal) 终端可用于远程访问[终端服务器](terminalServer.md)。只需对准[机架](../block/rack.md)里安装的[终端服务器](terminalServer.md)手持远程终端右击即可完成绑定。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminalserver.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminalserver.md index af56c51c55..340f754317 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminalserver.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/terminalserver.md @@ -1,5 +1,5 @@ # 终端服务器 -![远程查看](oredict:oc:terminalServer) +![远程查看](oredict:opencomputers:terminalServer) 终端服务器可向外界提供虚拟[屏幕](../block/screen1.md)和[键盘](../block/keyboard.md),可以通过绑定[终端](terminal.md)来控制机器。关于终端的更多信息可参阅[终端](terminal.md)条目。终端服务器必须安装在[机架](../block/rack.md)里面。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/texturepicker.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/texturepicker.md index 55a9e4ed84..594fb9d0b5 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/texturepicker.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/texturepicker.md @@ -1,6 +1,6 @@ # 纹理选择器 -![你说啥,这就是换了个皮肤?](oredict:oc:texturePicker) +![你说啥,这就是换了个皮肤?](oredict:opencomputers:texturePicker) 纹理选择器在制作 [3D 打印机](../block/printer.md)使用的模型时很有用。只需要潜行时对着某个方块使用它,就能获得世界上某个方块的纹理名。免责声明:对于箱子这种有特殊渲染器的方块无效。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tractorbeamupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tractorbeamupgrade.md index c9c6181fcb..6cc2c9374c 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tractorbeamupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tractorbeamupgrade.md @@ -1,5 +1,5 @@ # 牵引光束 -![把我传送过来。](oredict:oc:tractorBeamUpgrade) +![把我传送过来。](oredict:opencomputers:tractorBeamUpgrade) 牵引光束升级能让设备捡起 3 格内的物品。对树场或农场里面工作,或使用像是匠魂的某些工具那样有范围破坏能力的工具的[机器人](../block/robot.md)来说十分有用。每次操作都会尝试吸取范围内的一个物品实体,并消耗一定能量。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tradingupgrade.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tradingupgrade.md index 9a0d20ee39..9aaf00ac55 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/tradingupgrade.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/tradingupgrade.md @@ -1,5 +1,5 @@ # 交易升级 -![等价交换](oredict:oc:tradingUpgrade) +![等价交换](oredict:opencomputers:tradingUpgrade) 交易升级让设备能自动和村民这样的商人交易。它可以装在[机器人](../block/robot.md)和[无人机](drone.md)里面,安装后其能够探测附近商人的存在,获取可用交易信息并完成交易。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/transistor.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/transistor.md index 5c9e975a8a..89a9ffa109 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/transistor.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/transistor.md @@ -1,5 +1,5 @@ # 晶体管 -![我觉得我已无梗可用](oredict:oc:materialTransistor) +![我觉得我已无梗可用](oredict:opencomputers:materialTransistor) 晶体管是 OpenComputers 中最基础的元件,主要用于合成[芯片](chip1.md)等电子产品。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/upgradecontainer1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/upgradecontainer1.md index e932a9fb08..acdf83d984 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/upgradecontainer1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/upgradecontainer1.md @@ -1,5 +1,5 @@ # 升级组件容器 -![Can haz upgrade.](oredict:oc:upgradeContainer1) +![Can haz upgrade.](oredict:opencomputers:upgradeContainer1) 升级组件容器是一种特殊的[机器人](../block/robot.md)升级,它提供一个支持热插拔的升级槽位。它支持的升级的等级和它自身的等级一致。其复杂度是其等级的二倍,参阅[机器人](../block/robot.md)和[装配机](../block/assembler.md)的说明以了解复杂度的设定。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/wlancard1.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/wlancard1.md index 895d768072..a87ad22254 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/wlancard1.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/wlancard1.md @@ -1,6 +1,6 @@ # 无线网卡 -![可能致癌,也可能并不。](oredict:oc:wlanCard2) +![可能致癌,也可能并不。](oredict:opencomputers:wlanCard2) 无线网卡是支持无线网络的升级版[网卡](lanCard.md),有无线收发数据的能力。T2 的无线网卡还能收发有线数据。无线信号发射强度决定了信息可以传多远,这里信号强度等于方块距离。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/worldsensorcard.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/worldsensorcard.md index a46b9a7752..121fcab321 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/worldsensorcard.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/worldsensorcard.md @@ -1,5 +1,5 @@ # 世界传感器卡 -![勇敢前进……](oredict:oc:worldSensorCard) +![勇敢前进……](oredict:opencomputers:worldSensorCard) 世界传感器卡让设备能读取大气、(GalactiCraft 的)重力等世界信息,对于在空间中[机器人](../block/robot.md)和[无人机](drone.md)来说有用。 diff --git a/src/main/resources/assets/opencomputers/doc/zh_cn/item/wrench.md b/src/main/resources/assets/opencomputers/doc/zh_cn/item/wrench.md index 3b44fe43a5..f1e7374ced 100644 --- a/src/main/resources/assets/opencomputers/doc/zh_cn/item/wrench.md +++ b/src/main/resources/assets/opencomputers/doc/zh_cn/item/wrench.md @@ -1,5 +1,5 @@ # 螺丝刀扳手 -![瑞士制造。](oredict:oc:wrench) +![瑞士制造。](oredict:opencomputers:wrench) 和绝大多数科技主题的 Mod 一样,OpenComputers 也有它自己的扳手——一把融合了螺丝刀功能的扳手。看上去很难用。可以拿来旋转方块,也与其他很多 Mod 中支持各种扳手的设备兼容。 diff --git a/src/main/resources/assets/opencomputers/lang/de_DE.lang b/src/main/resources/assets/opencomputers/lang/de_DE.lang deleted file mode 100644 index 4cf64dd2c8..0000000000 --- a/src/main/resources/assets/opencomputers/lang/de_DE.lang +++ /dev/null @@ -1,483 +0,0 @@ -# German (de_DE) localization file -# Translations might not be 100% correct -# Suggestions for improvements are welcome - -# Blocks -tile.oc.adapter.name=Adapter -tile.oc.assembler.name=Elektronik-Werkbank -tile.oc.cable.name=Kabel -tile.oc.capacitor.name=Kondensator -tile.oc.carpetedcapacitor.name=Teppichkondensator -tile.oc.case1.name=Computergehäuse (Stufe 1) -tile.oc.case2.name=Computergehäuse (Stufe 2) -tile.oc.case3.name=Computergehäuse (Stufe 3) -tile.oc.caseCreative.name=Computergehäuse (Kreativ) -tile.oc.chameliumBlock.name=Chamälium-Block -tile.oc.charger.name=Ladestation -tile.oc.disassembler.name=Recycler -tile.oc.diskDrive.name=Diskettenlaufwerk -tile.oc.endstone.name=Endstein -tile.oc.geolyzer.name=Geolyzer -tile.oc.hologram1.name=Hologrammprojektor (Stufe 1) -tile.oc.hologram2.name=Hologrammprojektor (Stufe 2) -tile.oc.keyboard.name=Tastatur -tile.oc.microcontroller.name=Mikrocontroller -tile.oc.motionSensor.name=Bewegungsmelder -tile.oc.netSplitter.name=Net Splitter -tile.oc.powerConverter.name=Leistungswandler -tile.oc.powerDistributor.name=Stromverteiler -tile.oc.print.name=3D-Druck -tile.oc.printer.name=3D-Drucker -tile.oc.raid.name=Raid -tile.oc.redstone.name=Redstone-I/O -tile.oc.relay.name=Relais -tile.oc.robot.name=Roboter -tile.oc.robotAfterimage.name=Roboter -tile.oc.screen1.name=Bildschirm (Stufe 1) -tile.oc.screen2.name=Bildschirm (Stufe 2) -tile.oc.screen3.name=Bildschirm (Stufe 3) -tile.oc.rack.name=Serverschrank -tile.oc.transposer.name=Transposer -tile.oc.waypoint.name=Wegpunkt - -# Items -item.oc.AbstractBusCard.name=Abstrakter-Bus-Karte -item.oc.Acid.name=Grog -item.oc.ALU.name=Arithmetisch-logische Einheit (ALU) -item.oc.Analyzer.name=Messgerät -item.oc.APU0.name=Beschleunigter Prozessor (APU) (Stufe 1) -item.oc.APU1.name=Beschleunigter Prozessor (APU) (Stufe 2) -item.oc.APU2.name=Beschleunigter Prozessor (APU) (Kreativ) -item.oc.ArrowKeys.name=Pfeiltasten -item.oc.ButtonGroup.name=Tastengruppe -item.oc.CardBase.name=Kartenbasis -item.oc.Chamelium.name=Chamälium -item.oc.CircuitBoard.name=Leiterplatte -item.oc.ComponentBus0.name=Komponentenschnittstelle (Stufe 1) -item.oc.ComponentBus1.name=Komponentenschnittstelle (Stufe 2) -item.oc.ComponentBus2.name=Komponentenschnittstelle (Stufe 3) -item.oc.componentbus3.name=Komponentenschnittstelle (Kreativ) -item.oc.ControlUnit.name=Steuerwerk (CU) -item.oc.CPU0.name=Hauptprozessor (CPU) (Stufe 1) -item.oc.CPU1.name=Hauptprozessor (CPU) (Stufe 2) -item.oc.CPU2.name=Hauptprozessor (CPU) (Stufe 3) -item.oc.CuttingWire.name=Schneidedraht -item.oc.DataCard0.name=Datenkarte (Stufe 1) -item.oc.DataCard1.name=Datenkarte (Stufe 2) -item.oc.DataCard2.name=Datenkarte (Stufe 3) -item.oc.DebugCard.name=Debug-Karte -item.oc.Debugger.name=Netzwerk-Debugger -item.oc.DiamondChip.name=Diamantsplitter -item.oc.Disk.name=Platte -item.oc.DiskDriveMountable.name=Diskettenlaufwerk -item.oc.Drone.name=Drohne -item.oc.DroneCase0.name=Drohnengehäuse (Stufe 1) -item.oc.DroneCase1.name=Drohnengehäuse (Stufe 2) -item.oc.DroneCase3.name=Drohnengehäuse (Kreativ) -item.oc.eeprom.name=EEPROM -item.oc.FloppyDisk.name=Diskette -item.oc.GraphicsCard0.name=Grafikkarte (Stufe 1) -item.oc.GraphicsCard1.name=Grafikkarte (Stufe 2) -item.oc.GraphicsCard2.name=Grafikkarte (Stufe 3) -item.oc.HardDiskDrive0.name=Festplatte (Stufe 1) -item.oc.HardDiskDrive1.name=Festplatte (Stufe 2) -item.oc.HardDiskDrive2.name=Festplatte (Stufe 3) -item.oc.hoverBoots.name=Schwebestiefel -item.oc.InkCartridge.name=Tintenkartusche -item.oc.InkCartridgeEmpty.name=Tintenkartusche (Leer) -item.oc.InternetCard.name=Internetkarte -item.oc.Interweb.name=Internetz -item.oc.IronNugget.name=Eisennugget -item.oc.LinkedCard.name=Verknüpfte Karte -item.oc.Manual.name=OpenComputers-Handbuch -item.oc.Memory0.name=Speicher (Stufe 1) -item.oc.Memory1.name=Speicher (Stufe 1.5) -item.oc.Memory2.name=Speicher (Stufe 2) -item.oc.Memory3.name=Speicher (Stufe 2.5) -item.oc.Memory4.name=Speicher (Stufe 3) -item.oc.Memory5.name=Speicher (Stufe 3.5) -item.oc.Microchip0.name=Mikrochip (Stufe 1) -item.oc.Microchip1.name=Mikrochip (Stufe 2) -item.oc.Microchip2.name=Mikrochip (Stufe 3) -item.oc.MicrocontrollerCase0.name=Mikrocontroller-Gehäuse (Stufe 1) -item.oc.MicrocontrollerCase1.name=Mikrocontroller-Gehäuse (Stufe 2) -item.oc.MicrocontrollerCase3.name=Mikrocontroller-Gehäuse (Kreativ) -item.oc.Nanomachines.name=Nanomaschinen -item.oc.NetworkCard.name=Netzwerkkarte -item.oc.NumPad.name=Ziffernblock -item.oc.Present.name=Ein kleines Etwas... -item.oc.PrintedCircuitBoard.name=Gedruckte Leiterplatte (PCB) -item.oc.RawCircuitBoard.name=Leiterplattenrohling -item.oc.RedstoneCard0.name=Redstonekarte (Stufe 1) -item.oc.RedstoneCard1.name=Redstonekarte (Stufe 2) -item.oc.Server0.name=Server (Stufe 1) -item.oc.Server1.name=Server (Stufe 2) -item.oc.Server2.name=Server (Stufe 3) -item.oc.Server3.name=Server (Kreativ) -item.oc.Tablet.name=Tablet -item.oc.TabletCase0.name=Tablet-Gehäuse (Stufe 1) -item.oc.TabletCase1.name=Tablet-Gehäuse (Stufe 2) -item.oc.TabletCase3.name=Tablet-Gehäuse (Kreativ) -item.oc.Terminal.name=Fernbedienung -item.oc.TerminalServer.name=Terminalserver -item.oc.TexturePicker.name=Texturenwähler -item.oc.Transistor.name=Transistor -item.oc.UpgradeAngel.name=Schwebe-Upgrade -item.oc.UpgradeBattery0.name=Akku-Upgrade (Stufe 1) -item.oc.UpgradeBattery1.name=Akku-Upgrade (Stufe 2) -item.oc.UpgradeBattery2.name=Akku-Upgrade (Stufe 3) -item.oc.UpgradeChunkloader.name=Chunkloader-Upgrade -item.oc.UpgradeContainerCard0.name=Karten-Behälter (Stufe 1) -item.oc.UpgradeContainerCard1.name=Karten-Behälter (Stufe 2) -item.oc.UpgradeContainerCard2.name=Karten-Behälter (Stufe 3) -item.oc.UpgradeContainerUpgrade0.name=Upgrade-Behälter (Stufe 1) -item.oc.UpgradeContainerUpgrade1.name=Upgrade-Behälter (Stufe 2) -item.oc.UpgradeContainerUpgrade2.name=Upgrade-Behälter (Stufe 3) -item.oc.UpgradeCrafting.name=Crafting-Upgrade -item.oc.UpgradeDatabase0.name=Datenbank-Upgrade (Stufe 1) -item.oc.UpgradeDatabase1.name=Datenbank-Upgrade (Stufe 2) -item.oc.UpgradeDatabase2.name=Datenbank-Upgrade (Stufe 3) -item.oc.UpgradeExperience.name=Erfahrungs-Upgrade -item.oc.UpgradeGenerator.name=Generator-Upgrade -item.oc.UpgradeHover0.name=Schwebe-Upgrade (Stufe 1) -item.oc.UpgradeHover1.name=Schwebe-Upgrade (Stufe 2) -item.oc.UpgradeInventory.name=Inventar-Upgrade -item.oc.UpgradeInventoryController.name=Inventarbedienungs-Upgrade -item.oc.UpgradeLeash.name=Leinen-Upgrade -item.oc.UpgradeMF.name=MFU -item.oc.UpgradeNavigation.name=Navigations-Upgrade -item.oc.UpgradePiston.name=Kolben-Upgrade -item.oc.UpgradeSign.name=Schild-I/O-Upgrade -item.oc.UpgradeSolarGenerator.name=Solargenerator-Upgrade -item.oc.UpgradeTank.name=Tank-Upgrade -item.oc.UpgradeTankController.name=Tankbedienungs-Upgrade -item.oc.UpgradeTractorBeam.name=Traktorstrahl-Upgrade -item.oc.UpgradeTrading.name=Handels-Upgrade -item.oc.WirelessNetworkCard0.name=Drahtlosnetzwerkkarte (Stufe 1) -item.oc.WirelessNetworkCard1.name=Drahtlosnetzwerkkarte (Stufe 2) -item.oc.WorldSensorCard.name=Weltsensorkarte -item.oc.wrench.name=Schraubenziehschlüssel - -# Entities -entity.oc.Drone.name=Drohne - -# GUI -oc:gui.Analyzer.Address=§6Adresse§f: %s -oc:gui.Analyzer.AddressCopied=Adresse wurde in die Zwischenablage kopiert. -oc:gui.Analyzer.ChargerSpeed=§6Ladegeschwindigkeit§f: %s -oc:gui.Analyzer.ComponentName=§6Komponentenname§f: %s -oc:gui.Analyzer.Components=§6Anzahl verbundener Komponenten§f: %s -oc:gui.Analyzer.CopyToClipboard=In die Zwischenablage kopieren. -oc:gui.Analyzer.LastError=§6Letzter Fehler§f: %s -oc:gui.Analyzer.RobotName=§6Name§f: %s -oc:gui.Analyzer.RobotOwner=§6Besitzer§f: %s -oc:gui.Analyzer.RobotXp=§6Erfahrung§f: %s (Stufe %s) -oc:gui.Analyzer.StoredEnergy=§6Gespeicherte Energie§f: %s -oc:gui.Analyzer.TotalEnergy=§6Insgesamt gespeicherte Energie§f: %s -oc:gui.Analyzer.Users=§6Benutzer§f: %s -oc:gui.Analyzer.WirelessStrength=§6Signalstärke§f: %s -oc:gui.Assembler.Collect=Fertiges Gerät entnehmen -oc:gui.Assembler.Complexity=Komplexität: %s/%s -oc:gui.Assembler.InsertCase=Grundbaustein einlegen -oc:gui.Assembler.InsertCPU=CPU benötigt -oc:gui.Assembler.InsertRAM=RAM benötigt -oc:gui.Assembler.Progress=Fortschritt: %s%% (%s) -oc:gui.Assembler.Run=Zusammenbauen -oc:gui.Assembler.Warning.BIOS=BIOS -oc:gui.Assembler.Warning.GraphicsCard=Grafikkarte -oc:gui.Assembler.Warning.Inventory=Inventar-Upgrade -oc:gui.Assembler.Warning.Keyboard=Tastatur -oc:gui.Assembler.Warning.OS=Bootbares Medium -oc:gui.Assembler.Warning.Screen=Bildschirm -oc:gui.Assembler.Warnings=§eWarnung§7: Empfohlene Komponenten fehlen. -oc:gui.Chat.NewVersion=Eine neue Version ist verfügbar: %s -oc:gui.Chat.TextureName=§7Texturname ist §a%s§f. -oc:gui.Chat.WarningClassTransformer=Es gab §cFehler§f beim Ausführen des Class-Transformers. Bitte melde dies, zusammen mit deiner (vollständigen!) FML §alatest.log§f/§afml-server-latest.log§f Log-Datei, danke! -oc:gui.Chat.WarningFingerprint=§cWARNUNG§f - ungültige Signatur! Sollte '§a%s§f' sein, aber war '§e%s§f'. Falls du kein Modder bist und die "deobfuscated"-Version des Mods benutzt, solltest du OpenComputers erneut herunterladen, da die JAR, die du benutzt, vermutlich modifiziert wurde. -oc:gui.Chat.WarningLink=Link konnte nicht geöffnet werden: %s -oc:gui.Chat.WarningLuaFallback=Die native Lua-Implementierung ist nicht verfügbar. Computer können ihren Ausführungszustand nicht speichern. Sie werden automatisch neu starten, sobald ein Chunk neu geladen wird. -oc:gui.Chat.WarningProjectRed=Die verwendete Version von Project: Red ist nicht mit OpenComputers kompatibel. Aktualisiere bitte deine Version von Project: Red. -oc:gui.Chat.WarningRecipes=Es gab Fehler beim Laden eines oder mehrerer Rezepte. Einige Gegenstände können unter Umständen nicht gefertigt werden. Bitte wirf einen Blick in deine Log-Datei für weitere Informationen. -oc:gui.Chat.WarningSimpleComponent=Eine Erweiterung (deine?) welche das §aSimpleComponent§f-Interface verwendet, hat etwas §efalsch gemacht§f. Komponentenlogik konnte nicht eingefügt werden. Bitte wirf einen Blick in deine Log-Datei für weitere Informationen. -oc:gui.Drive.Managed=Managed -oc:gui.Drive.Unmanaged=Unmanaged -oc:gui.Drive.ReadOnlyLock=Sperre -oc:gui.Drive.ReadOnlyLockWarning=§lNur Lesen§r Sperre. Kann nur entfernt werden, wenn das Laufwerk gelöscht wird. -oc:gui.Drive.Warning=§lWarnung§r: Umschalten der Modi führt zum Datenverlust. -oc:gui.Error.ComponentOverflow=Zu viele Komponenten sind mit dem Computer verbunden. -oc:gui.Error.InternalError=Interner Fehler, bitte sieh in der Logdatei nach. Das ist wahrscheinlich ein Bug. -oc:gui.Error.NoCPU=Im Computer ist kein Hauptprozessor (CPU) installiert. -oc:gui.Error.NoEnergy=Nicht genug Energie. -oc:gui.Error.NoRAM=Im Computer ist kein RAM installiert. -oc:gui.Error.OutOfMemory=Nicht genug Arbeitsspeicher. -oc:gui.Manual.Blocks=OpenComputers-Blöcke -oc:gui.Manual.Home=Startseite -oc:gui.Manual.Items=OpenComputers-Gegenstände -oc:gui.Manual.Warning.BlockMissing=Block nicht verfügbar. -oc:gui.Manual.Warning.ImageMissing=Bild nicht gefunden. -oc:gui.Manual.Warning.ItemMissing=Gegenstand nicht verfügbar. -oc:gui.Manual.Warning.OreDictMissing=Ore-Dictionary-Eintrag nicht verfügbar. -oc:gui.Raid.Warning=§4Platten werden beim Einsetzen[nl] gelöscht. Entfernen einer Platte[nl] löscht das gesamte Raid. -oc:gui.Robot.Power=Energie -oc:gui.Robot.TurnOff=Ausschalten -oc:gui.Robot.TurnOn=Einschalten[nl] §7Nutze ein Messgerät, um Fehler zu behandeln.§r -oc:gui.Rack.Back=Hinten -oc:gui.Rack.Bottom=Unten -oc:gui.Rack.Left=Links -oc:gui.Rack.None=Keine -oc:gui.Rack.Right=Rechts -oc:gui.Rack.Enabled=Aktiv -oc:gui.Rack.Disabled=Inaktiv -oc:gui.Rack.Top=Oben -oc:gui.Switch.PacketsPerCycle=Pakete / Zyklus -oc:gui.Switch.QueueSize=Puffergröße -oc:gui.Switch.TransferRate=Taktung -oc:gui.Terminal.InvalidKey=Ungültiger Schlüssel, vermutlich wurde eine andere Fernbedienung an den Server gebunden. -oc:gui.Terminal.OutOfRange=Kein Signal. - -# Containers -oc:container.adapter=Adapter -oc:container.case=Computer -oc:container.charger=Ladestation -oc:container.disassembler=Recycler -oc:container.diskdrive=Diskettenlaufwerk -oc:container.printer=Drucker -oc:container.raid=Raid -oc:container.relay=Relais -oc:container.server=Server -oc:container.rack=Serverschrank -oc:container.tabletwrapper=Tablet - -# Keybinds -key.clipboardPaste=Zwischenablage einfügen - -# Item / Block Tooltips -oc:tooltip.accesspoint=Verhält sich wie ein Switch, aber empfängt zusätzlich Drahtlosnachrichten und leitet Pakete aus dem Festnetz drahtlos weiter. -oc:tooltip.abstractbuscard=Erlaubt es, LIP-Pakete des Abstrakten Busses von §fStargateTech 2§7 zu senden und zu empfangen. -oc:tooltip.acid=Eine hochgiftige Möchtegernflüssigkeit, wird üblicherweise nur von gewissen Piraten konsumiert. Mag sich aber auch zu anderen Zwecken eignen. -oc:tooltip.adapter=Erlaubt es, Blöcke anzusteuern, die keine Komponentenblöcke sind, wie etwa reguläre Minecraft-Blöcke oder Blöcke anderer Mods. -oc:tooltip.alu=Zählt Zahlen zum Zeitvertreib. Klingt komisch, is aber so. -oc:tooltip.analyzer=Erlaubt es, Informationen über Blöcke anzuzeigen, wie zum Bleistift ihre §fAdresse§7 und ihren §fKomponentennamen§7.[nl] Erlaubt zudem, den Fehler anzuzeigen, der zu einem Computerabsturz geführt hat, falls der Computer nicht regulär heruntergefahren wurde. -oc:tooltip.apu=Eine CPU mit integrierter GPU (bzw. IGP), falls du unbedingt den zusätzlichen Kartenslot brauchst.[nl] Unterstützte Komponenten: §f%s§7[nl] Höchstauflösung: §f%sx%s§7[nl] Maximale Farbtiefe: §f%s§7[nl] Operationen/Tick: §f%s§7 -oc:tooltip.assembler=Erlaubt die Fertigung von Robotern und weiteren Geräten aus diversen anderen Computerteilen. -oc:tooltip.cable=Ein billiger Weg, verschiedene Blöcke miteinander zu verbinden. -oc:tooltip.capacitor=Speichert Energie für spätere Verwendung. Kann extrem schnell befüllt und entleert werden. -oc:tooltip.carpetedcapacitor=Speichert Energie für den späteren Gebrauch. Kann sehr schnell befüllt und entleert werden. Lädt auf, wenn Schafe oder Ozelots darauf laufen. -oc:tooltip.cardbase=Wie der Name schon sagt, werden alle Erweiterungskarten hieraus hergestellt. -oc:tooltip.case=Das Computergehäuse ist der essentielle Grundbaustein für einen Computer. §fErweiterungskarten§7, §fRAM§7 und §fFestplatten§7 können in einem Gehäuse installiert werden.[nl] Slots: §f%s§7 -oc:tooltip.chamelium=Rohmaterial für 3D-Drucke. Nicht zum Verzehr geeignet: kann zu Erblindung und zeitweiligem Verlust von Präsenz führen. -oc:tooltip.chameliumblock=Schick und sauber. Praktisch für gefärbte Teile in 3D-Drucken, oder einfach, um deine tolle Basis mit einem schlichten, gefärbten Block zu dekorieren. -oc:tooltip.charger=Lädt Roboter mit Energie aus Kondensatoren auf. Die Ladegeschwindigkeit hängt vom eingehenden §fRedstonesignal§7 ab, wobei kein Signal "nicht laden" und ein Signal mit maximaler Stärke "schnellstmöglich laden" heißt. Erlaubt es auch Tablets zu laden, und ermöglicht Zugriff auf Festplatten in Tablets. -oc:tooltip.circuitboard=Mühsam ernährt sich das Eichhörnchen. Wenn es groß wird, wird es mal eine gedruckte Leiterplatte. -oc:tooltip.controlunit=Klingt wichtig, ist es auch. Man baut daraus immerhin CPUs. Wie könnte es da nicht wichtig sein. -oc:tooltip.componentbus=Diese Erweiterung erlaubt es es Servern, mit noch mehr Komponenten gleichzeitig zu kommunizieren, ähnlich wie CPUs.[nl] Unterstützte Komponenten: §f%s§7 -oc:tooltip.cpu=Kernstück eines jeden Computers. Die Taktrate hat einen leichten Schatten, aber was kann man von einer Taschensonnenuhr schon erwarten?[nl] Unterstützte Komponenten: §f%s§7 -oc:tooltip.cpu.Architecture=Architektur: §f%s§7 -oc:tooltip.cuttingwire=Wird gebraucht, um Tonblöcke in Leiterplattenform zu bekommen. Vermutlich das ineffizienteste Werkzeug in der Geschichte der Menschheit, da es nach einer Verwendung kaputt geht. -oc:tooltip.datacard0=Stellt einige komplexe Algorithmen wie Hash-Funktionen und deflate/inflate bereit. -oc:tooltip.datacard1=Stellt einige komplexe Algorithmen wie Hash-Funktionen und deflate/inflate bereit. -oc:tooltip.datacard2=Stellt einige komplexe Algorithmen wie Hash-Funktionen und deflate/inflate bereit. -oc:tooltip.debugcard=Kreativ-Modus-Gegenstand, erlaubt es die Welt zu manipulieren um das Testen zu erleichtern. Verwendung auf eigene Gefahr. -oc:tooltip.debugger=Erlaubt, Informationen über OCs internes Netzwerk auszugeben. Nur verwenden, wenn von einem Entwickler dazu aufgefordert. -oc:tooltip.diamondchip=Ein kleines Stück eines einst wunderschönen Diamanten. Er wird niemals wieder so sein, wie er war. -oc:tooltip.disassembler=Zerlegt Gegenstände in ihre Einzelteile. §lWarnung§7: zurückgewonnene Gegenstände haben eine %s%%-ige Chance beim Extrahieren kaputt zu gehen! -oc:tooltip.disk=Sehr einfaches Speichermedium, das verwendet werden kann, um Disketten und Festplatten zu fertigen. -oc:tooltip.diskdrive.CC=ComputerCraft-Disketten werden §aauch unterstützt§7. -oc:tooltip.diskdrive=Erlaubt es, Disketten zu lesen und zu beschreiben. Kann in Robotern installiert werden, um später Disketten einlegen zu können. -oc:tooltip.diskdrivemountable=Funktioniert genauso wie ein normales Diskettenlaufwerk, wird aber in einem Serverschrank installiert. -oc:tooltip.diskusage=Festplattennutzung: %s/%s Byte -oc:tooltip.disklocked=Gesperrt von %s -oc:tooltip.diskmodemanaged=Modus: Managed -oc:tooltip.diskmodeunmanaged=Modus: Unmanaged -oc:tooltip.drone=Drohnen sind schlichte, flinke Aufklärungseinheiten mit limitierter Inventargröße. -oc:tooltip.dronecase=Dieses Gehäuse wird verwendet, um Drohnen in der Elektronik-Werkbank zu bauen. Es bietet Platz für wenige Komponenten und kommt mit endsteinbetriebener Levitation. -oc:tooltip.eeprom=Kleiner, programmierbarer Speicher für das BIOS, das Computer zum starten verwenden. -oc:tooltip.fakeendstone=So gut wie echt, kann sogar schweben! -oc:tooltip.geolyzer=Erlaubt es die Härte der Blöcke in der Umgebung abzufragen. Hilfreich um Hologramme der Gegend zu erzeugen, oder um Erze zu entdecken. -oc:tooltip.graphicscard=Erlaubt es, den angezeigten Inhalt von Bildschirmen zu ändern.[nl] Höchstauflösung: §f%sx%s§7[nl] Maximale Farbtiefe: §f%s§7[nl] Operationen/Tick: §f%s§7 -oc:tooltip.hoverboots=Spring höher, fall tiefer, geh besser. Dies und noch mehr bekommst du mit den neuen, patentierten Schwebestiefeln (TM). -oc:tooltip.inkcartridge=Wird verwendet, um 3D-Drucker zu befüllen. Aus mysteriösen Gründen muss die Kartusche nicht fest im Drucker eingebaut werden. -oc:tooltip.inkcartridgeempty=Diese Kartusche wurde trocken gelegt. Fülle sie mit Farben wieder auf. Oder wirf sie weg. Mir doch egal. -oc:tooltip.internetcard=Diese Karte erlaubt es, HTTP-Anfragen zu senden und echte TCP-Sockets zu verwenden. -oc:tooltip.interweb=Kann in einer Internetkarte verwendet werden, um Computer mit dem rechtsfreien Raum kommunizieren zu lassen. -oc:tooltip.ironnugget=Ein Nugget, das aus Eisen besteht, darum wird es ja auch Eisennugget genannt, duh... -oc:tooltip.keyboard=Kann an Bildschirmen befestigt werden, um auf ihnen zu tippen. -oc:tooltip.hologram0=Ein Volumendisplay, das beliebige, von Computern festgelegte Voxelstrukturen anzeigt.[nl] Auflösung: §f48x32x48§7 [nl] Maximale Skalierung: §f3x§7 [nl] Farbtiefe: §fMonochrom§7 -oc:tooltip.hologram1=Ein Volumendisplay, das beliebige, von Computern festgelegte Voxelstrukturen anzeigt.[nl] Auflösung: §f48x32x48§7 [nl] Maximale Skalierung: §f4x§7 [nl] Farbtiefe: §fTricolor§7 -oc:tooltip.linkedcard=Diese Karten werden paarweise hergestellt, und können ausschließlich mit ihrer jeweilgen Partnerkarte kommunizieren, dafür allerdings über beliebige Entfernungen, und sogar über Dimensionen hinweg. Der Nachteil ist der hohe Energieverbrauch beim Senden einer Nachricht. -oc:tooltip.linkedcard_channel=§8Kanal: %s§7 -oc:tooltip.manual=Alles, was es über OpenComputers zu wissen gibt. Und mehr. Und das alles zu dem unglaublich niedrigen Preis von... §obitte R dücken, um fortzufahren§7. -oc:tooltip.materialcosts=Halte [§f%s§7] gedrückt für Materialkosten. -oc:tooltip.materials=Materialien: -oc:tooltip.memory=Braucht ein jeder Computer, um zu starten. Je mehr vorhanden, desto komplexere Programme können ausgeführt werden. -oc:tooltip.microchip=Tritt auch unter dem Alias Integrierter Schaltkreis auf. Keine Ahnung, warum das auch mit Redstone klappt, aber es funktioniert. -oc:tooltip.microcontroller=Mikrocontroller sind möglichst einfache Computer. Sie sind dazu gedacht, für Spezialfälle verwendet zu werden, bei denen sie einfach das Programm auf dem in ihnen eingebauten EEPROM ausführen sollen. -oc:tooltip.microcontrollercase=Dieses Gehäuse wird verwendet, um Mikrocontroller in der Elektronik-Werkbank zu bauen. Platziere es in eine solche und füge weitere Komponenten hinzu, um einen Mikrocontroller zu erstellen. -oc:tooltip.motionsensor=Kann Bewegungen sich in der Nähe befindender Lebewesen erkennen. Benötigt eine klare Sichtlinie. -oc:tooltip.nanomachines=Kontrolleinheit und eine Menge Nanomaschinen zur Einnahme, sofern du dich traust. -oc:tooltip.networkcard=Erlaubt es Computern, die über mehrere Blöcke miteinander verbunden sind (z.B. Kabel), mittels Netzwerknachrichten zu kommunizieren. -oc:tooltip.poweracceptor=Energiewandelgeschwindigkeit: §f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§fBuildCraft MJ§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§fFactorization Charge§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fIndustrialCraft² EU§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§fMekanism Joules§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fThermal Expansion RF§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fResonant Engine Coulombs§7: §a%s:%s§7 -oc:tooltip.powerconverter=Wandelt Strom anderer Mods in den internen Energietyp um. Umwandlungsverhältnisse: -oc:tooltip.powerdistributor=Verteilt Energie zwischen mehreren Netzwerken. Nützlich, um Energie mit einem Wandler auf mehrere Subnetze, die voneinander getrennt sein sollen, zu verteilen. -oc:tooltip.present=... für deine Mühen. Öffne dieses Geschenk für eine Chance, §kdolle Dinge§7 zu erhalten![nl]§8Fertige OpenComputers-Gegenstände zur rechten Zeit, und du hast die Chance ein Geschenk zu erhalten.§7 -oc:tooltip.print.BeaconBase=§8Funktioniert als Grundstein für ein Leuchtfeuer. -oc:tooltip.print.LightValue=§8Leuchtkraft: %s. -oc:tooltip.print.RedstoneLevel=§8Redstone-Signalstärke: %s. -oc:tooltip.printedcircuitboard=Hierauf basieren alle Erweiterungskarten, Speicher und so weiter. -oc:tooltip.printer=Erlaubt es, Blöcke aus benutzerdefinierten Formen zu drucken. Verwendet Chamälium und Tintenkartuschen. Muss über einen Computer konfiguriert werden. Von Kindern fern halten. Weil halt. -oc:tooltip.raid=Erlaubt es, drei Festplatten zu einem größeren Dateisystem zusammenzuschließen, welches von allen verbundenen Computern genutzt werden kann. -oc:tooltip.rawcircuitboard=Kann in einer Ofen-kompatiblen Schmelze freier Wahl gehärtet werden. -oc:tooltip.redstone=Erlaubt das Lesen und Ausgeben von Redstonesignalen um den Block herum. Kann von jedem Computer, der mit dem Block verbunden ist, gesteuert werden. Dieser Block ist quasi wie eine externe Redstonekarte. -oc:tooltip.redstonecard.ProjectRed=§fProjectRed§7 wird §aunterstützt§7. -oc:tooltip.redstonecard.RedLogic=§fRedLogic§7 wird §aunterstützt§7. -oc:tooltip.redstonecard.RedNet=§fRedNet§7 wird §aunterstützt§7. -oc:tooltip.redstonecard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 wird §aunterstützt§7. -oc:tooltip.redstonecard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 wird §aunterstützt§7. -oc:tooltip.redstonecard=Erlaubt das Lesen und Ausgeben von Redstonesignalen um den Computer oder Roboter herum. -oc:tooltip.relay=Erlaubt es, mehrere Netzwerke miteinander zu verbinden. Leitet ausschließlich Netzwerknachrichten weiter, Komponenten "hinter" dem Switch sind nicht sichtbar. Nützlich, um Netzwerke zu trennen, jedoch nach wie vor Kommunikation zwischen den Netzwerken zu erlauben, z.b. mittels Netzwerkkarten. -oc:tooltip.robot=Im Gegensatz zu normalen Computern können sich Roboter in der Welt bewegen und ähnlich wie Spieler mit der Welt interagieren. Sie können jedoch §onicht§r§7 mit externen Komponenten interagieren! -# The underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fStufe§7: §a%s§7. -oc:tooltip.robot_storedenergy=§fGespeicherte Energie§7: §a%s§7. -oc:tooltip.screen=Zeigt Text an, gesteuert von Grafikkarten in Computern.[nl] Höchstauflösung: §f%sx%s§7[nl] Maximale Farbtiefe: §f%s§7 -oc:tooltip.server=Ein Server kann wie ein gewöhnliches Computergehäuse mit Komponenten verbessert werden. Um den Server zu starten, muss er in einem Servergehäuse installiert werden. -oc:tooltip.server.Components=Installierte Komponenten: -oc:tooltip.rack=Erlaubt die Installation von bis zu vier Servern oder anderen Serverschrankkomponenten. -oc:tooltip.switch=Erlaubt es, mehrere Netzwerke miteinander zu verbinden. Leitet ausschließlich Netzwerknachrichten weiter, Komponenten "hinter" dem Switch sind nicht sichtbar. Nützlich, um Netzwerke zu trennen, jedoch nach wie vor Kommunikation zwischen den Netzwerken zu erlauben, z.B. mittels Netzwerkkarten. -oc:tooltip.tablet=Ein Tablet-PC, für Lua unterwegs. Kann durch Sneak-Aktivierung zwangsgestoppt werden. -oc:tooltip.tabletcase=Einfaches Gehäuse für Tablet-PCs. Kann in der Elektronik-Werkbank mit Komponenten bestückt werden, um einen Tablet-PC zu fertigen. -oc:tooltip.terminal=Erlaubt es, einen Server aus der Ferne zu steuern, so lange man sich in Reichweite des Servers befindet. Verhält sich wie Bildschirm und Tastatur in einem. Kann mit Shift-Rechtsklick an einen Server in einem Serverschrank gebunden werden. -oc:tooltip.terminalserver=Das Rückgrat für Fernzugriff. Fernbedienungen können hiermit verbunden werden. Enthält virtuelle Tastatur und Bildschirm. -oc:tooltip.texturepicker=Dieses Werkzeug erlaubt es, eine Zeichenkette anzuzeigen, die die Oberfläche eines Blocks beschreibt und in Form-Definitionen für 3D-Drucker verwendet werden kann. Definiv keine Texturnamen, oh nein. Nix da. -oc:tooltip.tier=§8Stufe %s -oc:tooltip.netsplitter=Kann Netzwerke dynamisch verbinden. Die Konnektivität jeder Seite kann umgeschaltet werden, in dem man "Professionelle Wartungsarbeiten" mit einem Schraubenschlüssel durchführt. Sie kann auch mit einem Redstone-Signal an entsprechenden Seiten invertiert werden. -oc:tooltip.toolong=Halte [§f%s§7] gedrückt für mehr Infos. -oc:tooltip.transistor=Elementarer Baustein der meisten Computerkomponenten. Nicht zu verwechseln mit Steinelementaren. -oc:tooltip.transposer=Ermöglicht automatischen Transfer von Items und Flüssigkeiten zwischen angrenzenden Blöcken. -oc:tooltip.upgradeangel=Erlaubt es Robotern, Blöcke in die Luft zu setzen, selbst wenn kein Referenzblock daneben existiert. -oc:tooltip.upgradebattery=Erhöht die Energiespeicherkapazität eines Roboters, was ihm erlaubt, länger zu arbeiten, ohne erneut aufgeladen werden zu müssen.[nl] Kapazität: §f%s§7 -oc:tooltip.upgradechunkloader=Wenn sich im Wald ein Roboter bewegt, und niemand da ist, ihn zu sehen, bewegt er sich dann wirklich? Dieses Upgrade stellt sicher, dass dem so ist. Es hält den Chunk, in dem sich der Roboter befindet, geladen, verbraucht jedoch Energie, während es aktiv ist. -oc:tooltip.upgradecontainercard=Dieses Behälter-Upgrade erlaubt es, eine Karte in einem bereits zusammengebauten Roboter zu installieren und wieder zu entfernen.[nl] Maximale Stufe: §f%s§7 -oc:tooltip.upgradecontainerupgrade=Dieses Behälter-Upgrade erlaubt es, ein Upgrade in einem bereits zusammengebauten Roboter zu installieren und wieder zu entfernen.[nl] Maximale Stufe: §f%s§7 -oc:tooltip.upgradecrafting=Ermöglicht Robotern, in dem oberen linken Bereich ihres Inventars Dinge zu fertigen. Gegenstände müssen so angeordnet sein, wie sie es in einer Werkbank wären. -oc:tooltip.upgradedatabase=Diese Upgrade erlaubt es, Gegenstandsinformationen - für spätere Verwendung in anderen Komponenten - zu speichern.[nl] Maximale Einträge: §f%s§7 -oc:tooltip.upgradeexperience=Dieses Upgrade erlaubt es Robotern, durch verschiedene Aktionen Erfahrung zu sammeln. Je mehr Erfahrung ein Roboter hat, desto mehr Energie kann er speichern, desto schneller kann er Blöcke abbauen und desto effizienter kann er mit Werkzeugen umgehen. -oc:tooltip.upgradegenerator=Kann verwendet werden, um unterwegs Energie aus Brennstoffen zu erzeugen. Verbraucht Gegenstände über einen ihrem Brennwert gemäßen Zeitraum.[nl] §fEffizienz§7: §a%s%%§7 -oc:tooltip.upgradehover=Erlaubt Robotern höher zu fliegen, ohne an Wänden klettern zu müssen.[nl] Maximalhöhe: §f%s§7 -oc:tooltip.upgradeinventory=Dieses Upgrade gibt Robotern ein internes Inventar. Ohne ein solches Upgrade können Roboter keine Gegenstände verwahren. -oc:tooltip.upgradeinventorycontroller=Dieses Upgrade erlaubt es dem Roboter, präziser mit externen Inventaren zu interagieren, und erlaubt es ihm, das angelegte Werkzeug mit einem Gegenstand in seinem Inventar auszutauschen. -oc:tooltip.upgrademf=Erlaubt es Adaptern, mit Blöcken zu interagieren, die etwas weiter weg sind. -oc:tooltip.upgrademf.Linked=§fVerbindung hergestellt§7 -oc:tooltip.upgrademf.Unlinked=§fKeine Verbindung§7 -oc:tooltip.upgradeleash=Erlaubt es manchen Geräten, wie etwa Drohnen, B- *getuschel* Verzeihung. Mir wurde soeben zugetragen, dass es tatsächlich dazu verwendet werden kann, Tiere an die Leine zu legen. Sogar viele Viecher. -oc:tooltip.upgradenavigation=Erlaubt es Robotern, ihre Position und Ausrichtung zu bestimmen. Die Position ist relativ zur Mitte der Karte, die in diesem Upgrade verbaut wurde. -oc:tooltip.upgradepiston=Dieses Upgrade ist sehr drückend. Es macht es möglich Blöcke zu verschieben, ähnlich dem Kolben. Es kann jedoch §lkeine§7 Entities bewegen. -oc:tooltip.upgradesign=Erlaubt das Lesen und Schreiben von Text auf Schildern. -oc:tooltip.upgradesolargenerator=Kann verwendet werden, um unterwegs Energie aus Sonnenlicht zu generieren. Benötigt eine ungehinderte Sicht zum Himmel über dem Roboter. Generiert Energie mit %s%% der Geschwindigkeit eines Stirlingmotors. -oc:tooltip.upgradetank=Dieses Upgrade gibt Robotern einen internen Tank. Ohne ein solches Upgrade können Roboter keine Flüssigkeiten verwahren. -oc:tooltip.upgradetankcontroller=Dieses Upgrade erlaubt es dem Roboter, präziser mit externen Tanks zu interagieren, und erlaubt es ihm, Flüssigkeiten in und aus sich im Inventar befindlichen Tank-Gegenständen zu pumpen. -oc:tooltip.upgradetractorbeam=Stattet den Roboter mit unglaublich fortschrittlicher Technologie - Kosename: "Gegenstandsmagnet" - aus. Erlaubt es dem Roboter, Gegenstände, innerhalb von 3 Blöcken um sich herum, einzusammeln. -oc:tooltip.waypoint=Ein Orientierungpunkt für Geräte mit einem Navigations-Upgrade. -oc:tooltip.wirelessnetworkcard=Erlaubt das drahtlose Senden von Netzwerknachrichten, zusätzlich zu normalen. Drahtlose Nachrichten werden nur gesendet, wenn eine §fSignalstärke§7 festgelegt wurde! -oc:tooltip.worldsensorcard=Erlaubt es, Informationen über die Welt auszulesen, wie etwa Gravitation und ob die Atmosphäre atembar ist. Verwendung von Messergebnissen auf eigene Gefahr. Der Hersteller übernimmt keinerlei Garantie. -oc:tooltip.wrench=Eine Mischung aus Schraubenzieher und Schraubenschlüssel, einfach zu benutzen, aber schwer zu meistern. - -#Achievements -achievement.oc.adapter=Steck mich ein -achievement.oc.adapter.desc=Interagiert mit Blöcken aus anderen Mods, und sogar Vanilla-Minecraft! -achievement.oc.assembler=Wundervoll -achievement.oc.assembler.desc=Zeit, die Welt zu erobern! -achievement.oc.cable=Kein gewöhnliches Kabel -achievement.oc.cable.desc=Mit patentierter Anti-Kabelsalat-Technologie. -achievement.oc.capacitor=Batterien enthalten -achievement.oc.capacitor.desc=Achtung: Kurzschlussgefahr. -achievement.oc.card=Wir akzeptieren Karten -achievement.oc.card.desc=Dreimal falsche PIN-Eingabe. Karte wird einbehalten. -achievement.oc.case=Desktop-Computer -achievement.oc.case.desc=Desktop (und Betriebssystem) separat erhältlich. -achievement.oc.charger=Die Spannung steigt -achievement.oc.charger.desc=Und auflad- verdammt, schon wieder das Redstone-Signal vergessen. -achievement.oc.chip=Technischer Fortschritt -achievement.oc.chip.desc=Besser als Elekrtonenröhren. -achievement.oc.cpu=Übertaktet -achievement.oc.cpu.desc=Endlich ein Nutzen für die ungenutzten Prozessorzyklen. -achievement.oc.disassembler=Nochmal von vorn -achievement.oc.disassembler.desc=Falls deine brillianten Ideen am Ende doch nicht so brilliant sind. -achievement.oc.diskDrive=*klick brumm brumm brumm ratter* -achievement.oc.diskDrive.desc=Weniger Speicherplatz, aber welch ein wundervolles Geräusch. -achievement.oc.drone=Startbereit -achievement.oc.drone.desc=Keep calm and nuke it from orbit. -achievement.oc.eeprom=Es kann nur einen geben -achievement.oc.eeprom.desc=Pro Computer, genau genommen. Für eine deterministische Boot-Reihenfolge, weißt du? -achievement.oc.floppy=Der Eine Ri- Datenspeicher -achievement.oc.floppy.desc=Nicht zu verwechseln mit Flappy. -achievement.oc.geolyzer=Gezielte Rohstoffsuche -achievement.oc.geolyzer.desc=Umweltfreundlicher als Fracking, versprochen. -achievement.oc.graphicsCard=LastGen -achievement.oc.graphicsCard.desc=The way it's meant to be... äh... rendered. Ja. So ungefähr. -achievement.oc.hdd=Hotdog-Dealer -achievement.oc.hdd.desc=Moment, das stimmt nicht ganz. Warte, gleich hab' ich's... -achievement.oc.hologram=Eine höhere Dimension -achievement.oc.hologram.desc=Weil 2D so langweilig ist. Oder ist es das wirklich? -achievement.oc.keyboard=SchmutzFänger3000 -achievement.oc.keyboard.desc=Es wird davon abgeraten, sie umzudrehen und zu schütteln, auch wenn es noch so verlockend ist. -achievement.oc.microcontroller=Kleine Schwester -achievement.oc.microcontroller.desc=Das kleine Geschwisterkind des Computers. -achievement.oc.motionSensor=Got the Moves -achievement.oc.motionSensor.desc=Like Steve Swagger. -achievement.oc.networkCard=Fernleitung -achievement.oc.networkCard.desc=Perfekt um diese transitiven Beziehungen aufrecht zu erhalten. -achievement.oc.openOS=Boot -achievement.oc.openOS.desc=Das Eine Betrieb- wie, was meinst du, der Witz wird alt? -achievement.oc.powerDistributor=Strom-Sharing -achievement.oc.powerDistributor.desc=ElektroVZ ist so 2010. -achievement.oc.rack=Multifunktionsschrank -achievement.oc.rack.desc=Wird unter Anderem in Kantinen genutzt, um gebrauchte Tabletts zu sammeln. -achievement.oc.raid=Suche Team -achievement.oc.raid.desc=Heroic plzkthx. -achievement.oc.ram=Random Access Memories -achievement.oc.ram.desc=Congratulations, you're Doin' It Right. -achievement.oc.redstoneCard=Kontakt -achievement.oc.redstoneCard.desc=Zeit für analoge Signale. -achievement.oc.redstoneIO=Außenseiter -achievement.oc.redstoneIO.desc=Redstone-Signale, dort wo du sie brauchst. -achievement.oc.robot=Beep Boop -achievement.oc.robot.desc=VERNICHTEN! -achievement.oc.screen=Hast du schon versucht, ihn aus- und wieder anzuschalten? -achievement.oc.screen.desc=Nein, ernsthaft. Ein Redstone-Impuls kann wirklich einen Bildschirm an- und ausschalten. -achievement.oc.server=Dediziert -achievement.oc.server.desc=Hier kommen die Cloud-Dienste. -achievement.oc.switch=Paketdienst -achievement.oc.switch.desc=Nicht für Hinkelsteine verwenden, die könnten sonst beim Aussortieren verloren gehen. -achievement.oc.tablet=Verschluckbare Kleinteile -achievement.oc.tablet.desc=Von Kindern fernhalten, um unerwünschte Kreditkartenbelastungen zu vermeiden. -achievement.oc.transistor=Schöne Grüße an Red! -achievement.oc.transistor.desc=Jetzt kannst du dir den Soundtrack anhören. -achievement.oc.wirelessNetworkCard=Das WLAN - Unendliche Weiten -achievement.oc.wirelessNetworkCard.desc=Netzwerke, die nie ein Paket zuvor gesehen hat. - -# Death messages. Note that the number of entries here must match the number -# set in the actual damage source in code. -death.attack.oc.nanomachinesOverload.1=%s ist zu gierig geworden. -death.attack.oc.nanomachinesOverload.2=%s erlitt einen Nervenzusammenbruch. -death.attack.oc.nanomachinesOverload.3=Die Nanomaschinen von %s gerieten wohl außer Kontrolle. Ups. -death.attack.oc.nanomachinesHungry.1=%s wurde von Nanomaschinen verspeist. -death.attack.oc.nanomachinesHungry.2=%s hat wohl seine Nanomaschinen nicht gefüttert. -death.attack.oc.nanomachinesHungry.3=%s wurde verdaut. - -# NEI Integration -nei.options.inventory.oredict=OreDictionary-Namen anzeigen -nei.options.inventory.oredict.true=True -nei.options.inventory.oredict.false=False -nei.usage.oc.Manual=Handbuch öffnen - -# Waila Integration -option.oc.address=Adresse -option.oc.componentName=Komponentenname -option.oc.energy=Energie diff --git a/src/main/resources/assets/opencomputers/lang/de_de.json b/src/main/resources/assets/opencomputers/lang/de_de.json new file mode 100644 index 0000000000..d5b7cc62d3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/de_de.json @@ -0,0 +1,460 @@ +{ + "tile.oc.adapter": "Adapter", + "tile.oc.assembler": "Elektronik-Werkbank", + "tile.oc.cable": "Kabel", + "tile.oc.capacitor": "Kondensator", + "tile.oc.carpetedcapacitor": "Teppichkondensator", + "tile.oc.case1": "Computergehäuse (Stufe 1)", + "tile.oc.case2": "Computergehäuse (Stufe 2)", + "tile.oc.case3": "Computergehäuse (Stufe 3)", + "tile.oc.caseCreative": "Computergehäuse (Kreativ)", + "tile.oc.chameliumBlock": "Chamälium-Block", + "tile.oc.charger": "Ladestation", + "tile.oc.disassembler": "Recycler", + "tile.oc.diskDrive": "Diskettenlaufwerk", + "tile.oc.endstone": "Endstein", + "tile.oc.geolyzer": "Geolyzer", + "tile.oc.hologram1": "Hologrammprojektor (Stufe 1)", + "tile.oc.hologram2": "Hologrammprojektor (Stufe 2)", + "tile.oc.keyboard": "Tastatur", + "tile.oc.microcontroller": "Mikrocontroller", + "tile.oc.motionSensor": "Bewegungsmelder", + "tile.oc.netSplitter": "Net Splitter", + "tile.oc.powerConverter": "Leistungswandler", + "tile.oc.powerDistributor": "Stromverteiler", + "tile.oc.print": "3D-Druck", + "tile.oc.printer": "3D-Drucker", + "tile.oc.raid": "Raid", + "tile.oc.redstone": "Redstone-I/O", + "tile.oc.relay": "Relais", + "tile.oc.robot": "Roboter", + "tile.oc.robotAfterimage": "Roboter", + "tile.oc.screen1": "Bildschirm (Stufe 1)", + "tile.oc.screen2": "Bildschirm (Stufe 2)", + "tile.oc.screen3": "Bildschirm (Stufe 3)", + "tile.oc.rack": "Serverschrank", + "tile.oc.transposer": "Transposer", + "tile.oc.waypoint": "Wegpunkt", + "item.oc.AbstractBusCard": "Abstrakter-Bus-Karte", + "item.oc.Acid": "Grog", + "item.oc.ALU": "Arithmetisch-logische Einheit (ALU)", + "item.oc.Analyzer": "Messgerät", + "item.oc.APU0": "Beschleunigter Prozessor (APU) (Stufe 1)", + "item.oc.APU1": "Beschleunigter Prozessor (APU) (Stufe 2)", + "item.oc.APU2": "Beschleunigter Prozessor (APU) (Kreativ)", + "item.oc.ArrowKeys": "Pfeiltasten", + "item.oc.ButtonGroup": "Tastengruppe", + "item.oc.CardBase": "Kartenbasis", + "item.oc.Chamelium": "Chamälium", + "item.oc.CircuitBoard": "Leiterplatte", + "item.oc.ComponentBus0": "Komponentenschnittstelle (Stufe 1)", + "item.oc.ComponentBus1": "Komponentenschnittstelle (Stufe 2)", + "item.oc.ComponentBus2": "Komponentenschnittstelle (Stufe 3)", + "item.oc.componentbus3": "Komponentenschnittstelle (Kreativ)", + "item.oc.ControlUnit": "Steuerwerk (CU)", + "item.oc.CPU0": "Hauptprozessor (CPU) (Stufe 1)", + "item.oc.CPU1": "Hauptprozessor (CPU) (Stufe 2)", + "item.oc.CPU2": "Hauptprozessor (CPU) (Stufe 3)", + "item.oc.CuttingWire": "Schneidedraht", + "item.oc.DataCard0": "Datenkarte (Stufe 1)", + "item.oc.DataCard1": "Datenkarte (Stufe 2)", + "item.oc.DataCard2": "Datenkarte (Stufe 3)", + "item.oc.DebugCard": "Debug-Karte", + "item.oc.Debugger": "Netzwerk-Debugger", + "item.oc.DiamondChip": "Diamantsplitter", + "item.oc.Disk": "Platte", + "item.oc.DiskDriveMountable": "Diskettenlaufwerk", + "item.oc.Drone": "Drohne", + "item.oc.DroneCase0": "Drohnengehäuse (Stufe 1)", + "item.oc.DroneCase1": "Drohnengehäuse (Stufe 2)", + "item.oc.DroneCase3": "Drohnengehäuse (Kreativ)", + "item.oc.eeprom": "EEPROM", + "item.oc.FloppyDisk": "Diskette", + "item.oc.GraphicsCard0": "Grafikkarte (Stufe 1)", + "item.oc.GraphicsCard1": "Grafikkarte (Stufe 2)", + "item.oc.GraphicsCard2": "Grafikkarte (Stufe 3)", + "item.oc.HardDiskDrive0": "Festplatte (Stufe 1)", + "item.oc.HardDiskDrive1": "Festplatte (Stufe 2)", + "item.oc.HardDiskDrive2": "Festplatte (Stufe 3)", + "item.oc.hoverBoots": "Schwebestiefel", + "item.oc.InkCartridge": "Tintenkartusche", + "item.oc.InkCartridgeEmpty": "Tintenkartusche (Leer)", + "item.oc.InternetCard": "Internetkarte", + "item.oc.Interweb": "Internetz", + "item.oc.IronNugget": "Eisennugget", + "item.oc.LinkedCard": "Verknüpfte Karte", + "item.oc.Manual": "OpenComputers-Handbuch", + "item.oc.Memory0": "Speicher (Stufe 1)", + "item.oc.Memory1": "Speicher (Stufe 1.5)", + "item.oc.Memory2": "Speicher (Stufe 2)", + "item.oc.Memory3": "Speicher (Stufe 2.5)", + "item.oc.Memory4": "Speicher (Stufe 3)", + "item.oc.Memory5": "Speicher (Stufe 3.5)", + "item.oc.Microchip0": "Mikrochip (Stufe 1)", + "item.oc.Microchip1": "Mikrochip (Stufe 2)", + "item.oc.Microchip2": "Mikrochip (Stufe 3)", + "item.oc.MicrocontrollerCase0": "Mikrocontroller-Gehäuse (Stufe 1)", + "item.oc.MicrocontrollerCase1": "Mikrocontroller-Gehäuse (Stufe 2)", + "item.oc.MicrocontrollerCase3": "Mikrocontroller-Gehäuse (Kreativ)", + "item.oc.Nanomachines": "Nanomaschinen", + "item.oc.NetworkCard": "Netzwerkkarte", + "item.oc.NumPad": "Ziffernblock", + "item.oc.Present": "Ein kleines Etwas...", + "item.oc.PrintedCircuitBoard": "Gedruckte Leiterplatte (PCB)", + "item.oc.RawCircuitBoard": "Leiterplattenrohling", + "item.oc.RedstoneCard0": "Redstonekarte (Stufe 1)", + "item.oc.RedstoneCard1": "Redstonekarte (Stufe 2)", + "item.oc.Server0": "Server (Stufe 1)", + "item.oc.Server1": "Server (Stufe 2)", + "item.oc.Server2": "Server (Stufe 3)", + "item.oc.Server3": "Server (Kreativ)", + "item.oc.Tablet": "Tablet", + "item.oc.TabletCase0": "Tablet-Gehäuse (Stufe 1)", + "item.oc.TabletCase1": "Tablet-Gehäuse (Stufe 2)", + "item.oc.TabletCase3": "Tablet-Gehäuse (Kreativ)", + "item.oc.Terminal": "Fernbedienung", + "item.oc.TerminalServer": "Terminalserver", + "item.oc.TexturePicker": "Texturenwähler", + "item.oc.Transistor": "Transistor", + "item.oc.UpgradeAngel": "Schwebe-Upgrade", + "item.oc.UpgradeBattery0": "Akku-Upgrade (Stufe 1)", + "item.oc.UpgradeBattery1": "Akku-Upgrade (Stufe 2)", + "item.oc.UpgradeBattery2": "Akku-Upgrade (Stufe 3)", + "item.oc.UpgradeChunkloader": "Chunkloader-Upgrade", + "item.oc.UpgradeContainerCard0": "Karten-Behälter (Stufe 1)", + "item.oc.UpgradeContainerCard1": "Karten-Behälter (Stufe 2)", + "item.oc.UpgradeContainerCard2": "Karten-Behälter (Stufe 3)", + "item.oc.UpgradeContainerUpgrade0": "Upgrade-Behälter (Stufe 1)", + "item.oc.UpgradeContainerUpgrade1": "Upgrade-Behälter (Stufe 2)", + "item.oc.UpgradeContainerUpgrade2": "Upgrade-Behälter (Stufe 3)", + "item.oc.UpgradeCrafting": "Crafting-Upgrade", + "item.oc.UpgradeDatabase0": "Datenbank-Upgrade (Stufe 1)", + "item.oc.UpgradeDatabase1": "Datenbank-Upgrade (Stufe 2)", + "item.oc.UpgradeDatabase2": "Datenbank-Upgrade (Stufe 3)", + "item.oc.UpgradeExperience": "Erfahrungs-Upgrade", + "item.oc.UpgradeGenerator": "Generator-Upgrade", + "item.oc.UpgradeHover0": "Schwebe-Upgrade (Stufe 1)", + "item.oc.UpgradeHover1": "Schwebe-Upgrade (Stufe 2)", + "item.oc.UpgradeInventory": "Inventar-Upgrade", + "item.oc.UpgradeInventoryController": "Inventarbedienungs-Upgrade", + "item.oc.UpgradeLeash": "Leinen-Upgrade", + "item.oc.UpgradeMF": "MFU", + "item.oc.UpgradeNavigation": "Navigations-Upgrade", + "item.oc.UpgradePiston": "Kolben-Upgrade", + "item.oc.UpgradeSign": "Schild-I/O-Upgrade", + "item.oc.UpgradeSolarGenerator": "Solargenerator-Upgrade", + "item.oc.UpgradeTank": "Tank-Upgrade", + "item.oc.UpgradeTankController": "Tankbedienungs-Upgrade", + "item.oc.UpgradeTractorBeam": "Traktorstrahl-Upgrade", + "item.oc.UpgradeTrading": "Handels-Upgrade", + "item.oc.WirelessNetworkCard0": "Drahtlosnetzwerkkarte (Stufe 1)", + "item.oc.WirelessNetworkCard1": "Drahtlosnetzwerkkarte (Stufe 2)", + "item.oc.WorldSensorCard": "Weltsensorkarte", + "item.oc.wrench": "Schraubenziehschlüssel", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.Drone": "Drohne", + "oc:gui.Analyzer.Address": "§6Adresse§f: %s", + "oc:gui.Analyzer.AddressCopied": "Adresse wurde in die Zwischenablage kopiert.", + "oc:gui.Analyzer.ChargerSpeed": "§6Ladegeschwindigkeit§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Komponentenname§f: %s", + "oc:gui.Analyzer.Components": "§6Anzahl verbundener Komponenten§f: %s", + "oc:gui.Analyzer.CopyToClipboard": "In die Zwischenablage kopieren.", + "oc:gui.Analyzer.LastError": "§6Letzter Fehler§f: %s", + "oc:gui.Analyzer.RobotName": "§6Name§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Besitzer§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Erfahrung§f: %s (Stufe %s)", + "oc:gui.Analyzer.StoredEnergy": "§6Gespeicherte Energie§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Insgesamt gespeicherte Energie§f: %s", + "oc:gui.Analyzer.Users": "§6Benutzer§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6Signalstärke§f: %s", + "oc:gui.Assembler.Collect": "Fertiges Gerät entnehmen", + "oc:gui.Assembler.Complexity": "Komplexität: %s/%s", + "oc:gui.Assembler.InsertCase": "Grundbaustein einlegen", + "oc:gui.Assembler.InsertCPU": "CPU benötigt", + "oc:gui.Assembler.InsertRAM": "RAM benötigt", + "oc:gui.Assembler.Progress": "Fortschritt: %s%% (%s)", + "oc:gui.Assembler.Run": "Zusammenbauen", + "oc:gui.Assembler.Warning.BIOS": "BIOS", + "oc:gui.Assembler.Warning.GraphicsCard": "Grafikkarte", + "oc:gui.Assembler.Warning.Inventory": "Inventar-Upgrade", + "oc:gui.Assembler.Warning.Keyboard": "Tastatur", + "oc:gui.Assembler.Warning.OS": "Bootbares Medium", + "oc:gui.Assembler.Warning.Screen": "Bildschirm", + "oc:gui.Assembler.Warnings": "§eWarnung§7: Empfohlene Komponenten fehlen.", + "oc:gui.Chat.NewVersion": "Eine neue Version ist verfügbar: %s", + "oc:gui.Chat.TextureName": "§7Texturname ist §a%s§f.", + "oc:gui.Chat.WarningClassTransformer": "Es gab §cFehler§f beim Ausführen des Class-Transformers. Bitte melde dies, zusammen mit deiner (vollständigen!) FML §alatest.log§f/§afml-server-latest.log§f Log-Datei, danke!", + "oc:gui.Chat.WarningFingerprint": "§cWARNUNG§f - ungültige Signatur! Sollte '§a%s§f' sein, aber war '§e%s§f'. Falls du kein Modder bist und die \"deobfuscated\"-Version des Mods benutzt, solltest du OpenComputers erneut herunterladen, da die JAR, die du benutzt, vermutlich modifiziert wurde.", + "oc:gui.Chat.WarningLink": "Link konnte nicht geöffnet werden: %s", + "oc:gui.Chat.WarningLuaFallback": "Die native Lua-Implementierung ist nicht verfügbar. Computer können ihren Ausführungszustand nicht speichern. Sie werden automatisch neu starten, sobald ein Chunk neu geladen wird.", + "oc:gui.Chat.WarningProjectRed": "Die verwendete Version von Project: Red ist nicht mit OpenComputers kompatibel. Aktualisiere bitte deine Version von Project: Red.", + "oc:gui.Chat.WarningRecipes": "Es gab Fehler beim Laden eines oder mehrerer Rezepte. Einige Gegenstände können unter Umständen nicht gefertigt werden. Bitte wirf einen Blick in deine Log-Datei für weitere Informationen.", + "oc:gui.Drive.Managed": "Managed", + "oc:gui.Drive.Unmanaged": "Unmanaged", + "oc:gui.Drive.ReadOnlyLock": "Sperre", + "oc:gui.Drive.ReadOnlyLockWarning": "§lNur Lesen§r Sperre. Kann nur entfernt werden, wenn das Laufwerk gelöscht wird.", + "oc:gui.Drive.Warning": "§lWarnung§r: Umschalten der Modi führt zum Datenverlust.", + "oc:gui.Error.ComponentOverflow": "Zu viele Komponenten sind mit dem Computer verbunden.", + "oc:gui.Error.InternalError": "Interner Fehler, bitte sieh in der Logdatei nach. Das ist wahrscheinlich ein Bug.", + "oc:gui.Error.NoCPU": "Im Computer ist kein Hauptprozessor (CPU) installiert.", + "oc:gui.Error.NoEnergy": "Nicht genug Energie.", + "oc:gui.Error.NoRAM": "Im Computer ist kein RAM installiert.", + "oc:gui.Error.OutOfMemory": "Nicht genug Arbeitsspeicher.", + "oc:gui.Manual.Blocks": "OpenComputers-Blöcke", + "oc:gui.Manual.Home": "Startseite", + "oc:gui.Manual.Items": "OpenComputers-Gegenstände", + "oc:gui.Manual.Warning.BlockMissing": "Block nicht verfügbar.", + "oc:gui.Manual.Warning.ImageMissing": "Bild nicht gefunden.", + "oc:gui.Manual.Warning.ItemMissing": "Gegenstand nicht verfügbar.", + "oc:gui.Manual.Warning.OreDictMissing": "Ore-Dictionary-Eintrag nicht verfügbar.", + "oc:gui.Raid.Warning": "§4Platten werden beim Einsetzen\ngelöscht. Entfernen einer Platte\nlöscht das gesamte Raid.", + "oc:gui.Robot.Power": "Energie", + "oc:gui.Robot.TurnOff": "Ausschalten", + "oc:gui.Robot.TurnOn": "Einschalten\n§7Nutze ein Messgerät, um Fehler zu behandeln.§r", + "oc:gui.Rack.Back": "Hinten", + "oc:gui.Rack.Bottom": "Unten", + "oc:gui.Rack.Left": "Links", + "oc:gui.Rack.None": "Keine", + "oc:gui.Rack.Right": "Rechts", + "oc:gui.Rack.Enabled": "Aktiv", + "oc:gui.Rack.Disabled": "Inaktiv", + "oc:gui.Rack.Top": "Oben", + "oc:gui.Switch.PacketsPerCycle": "Pakete / Zyklus", + "oc:gui.Switch.QueueSize": "Puffergröße", + "oc:gui.Switch.TransferRate": "Taktung", + "oc:gui.Terminal.InvalidKey": "Ungültiger Schlüssel, vermutlich wurde eine andere Fernbedienung an den Server gebunden.", + "oc:gui.Terminal.OutOfRange": "Kein Signal.", + "oc:container.adapter": "Adapter", + "oc:container.case": "Computer", + "oc:container.charger": "Ladestation", + "oc:container.disassembler": "Recycler", + "oc:container.diskdrive": "Diskettenlaufwerk", + "oc:container.printer": "Drucker", + "oc:container.raid": "Raid", + "oc:container.relay": "Relais", + "oc:container.server": "Server", + "oc:container.rack": "Serverschrank", + "oc:container.tabletwrapper": "Tablet", + "key.opencomputers.analyzeCopyAddress": "Adresse kopieren (Messgerät)", + "key.opencomputers.clipboardPaste": "Zwischenablage einfügen", + "key.opencomputers.extendedTooltip": "Mehr Infos anzeigen", + "oc:tooltip.accesspoint": "Verhält sich wie ein Switch, aber empfängt zusätzlich Drahtlosnachrichten und leitet Pakete aus dem Festnetz drahtlos weiter.", + "oc:tooltip.abstractbuscard": "Erlaubt es, LIP-Pakete des Abstrakten Busses von §fStargateTech 2§7 zu senden und zu empfangen.", + "oc:tooltip.acid": "Eine hochgiftige Möchtegernflüssigkeit, wird üblicherweise nur von gewissen Piraten konsumiert. Mag sich aber auch zu anderen Zwecken eignen.", + "oc:tooltip.adapter": "Erlaubt es, Blöcke anzusteuern, die keine Komponentenblöcke sind, wie etwa reguläre Minecraft-Blöcke oder Blöcke anderer Mods.", + "oc:tooltip.alu": "Zählt Zahlen zum Zeitvertreib. Klingt komisch, is aber so.", + "oc:tooltip.analyzer": "Erlaubt es, Informationen über Blöcke anzuzeigen, wie zum Bleistift ihre §fAdresse§7 und ihren §fKomponentennamen§7.\nErlaubt zudem, den Fehler anzuzeigen, der zu einem Computerabsturz geführt hat, falls der Computer nicht regulär heruntergefahren wurde.", + "oc:tooltip.apu": "Eine CPU mit integrierter GPU (bzw. IGP), falls du unbedingt den zusätzlichen Kartenslot brauchst.\nUnterstützte Komponenten: §f%s§7\nHöchstauflösung: §f%sx%s§7\nMaximale Farbtiefe: §f%s§7\nOperationen/Tick: §f%s§7", + "oc:tooltip.assembler": "Erlaubt die Fertigung von Robotern und weiteren Geräten aus diversen anderen Computerteilen.", + "oc:tooltip.cable": "Ein billiger Weg, verschiedene Blöcke miteinander zu verbinden.", + "oc:tooltip.capacitor": "Speichert Energie für spätere Verwendung. Kann extrem schnell befüllt und entleert werden.", + "oc:tooltip.carpetedcapacitor": "Speichert Energie für den späteren Gebrauch. Kann sehr schnell befüllt und entleert werden. Lädt auf, wenn Schafe oder Ozelots darauf laufen.", + "oc:tooltip.cardbase": "Wie der Name schon sagt, werden alle Erweiterungskarten hieraus hergestellt.", + "oc:tooltip.case": "Das Computergehäuse ist der essentielle Grundbaustein für einen Computer. §fErweiterungskarten§7, §fRAM§7 und §fFestplatten§7 können in einem Gehäuse installiert werden.\nSlots: §f%s§7", + "oc:tooltip.chamelium": "Rohmaterial für 3D-Drucke. Nicht zum Verzehr geeignet: kann zu Erblindung und zeitweiligem Verlust von Präsenz führen.", + "oc:tooltip.chameliumblock": "Schick und sauber. Praktisch für gefärbte Teile in 3D-Drucken, oder einfach, um deine tolle Basis mit einem schlichten, gefärbten Block zu dekorieren.", + "oc:tooltip.charger": "Lädt Roboter mit Energie aus Kondensatoren auf. Die Ladegeschwindigkeit hängt vom eingehenden §fRedstonesignal§7 ab, wobei kein Signal \"nicht laden\" und ein Signal mit maximaler Stärke \"schnellstmöglich laden\" heißt. Erlaubt es auch Tablets zu laden, und ermöglicht Zugriff auf Festplatten in Tablets.", + "oc:tooltip.circuitboard": "Mühsam ernährt sich das Eichhörnchen. Wenn es groß wird, wird es mal eine gedruckte Leiterplatte.", + "oc:tooltip.controlunit": "Klingt wichtig, ist es auch. Man baut daraus immerhin CPUs. Wie könnte es da nicht wichtig sein.", + "oc:tooltip.componentbus": "Diese Erweiterung erlaubt es es Servern, mit noch mehr Komponenten gleichzeitig zu kommunizieren, ähnlich wie CPUs.\nUnterstützte Komponenten: §f%s§7", + "oc:tooltip.cpu": "Kernstück eines jeden Computers. Die Taktrate hat einen leichten Schatten, aber was kann man von einer Taschensonnenuhr schon erwarten?\nUnterstützte Komponenten: §f%s§7", + "oc:tooltip.cpu.Architecture": "Architektur: §f%s§7", + "oc:tooltip.cuttingwire": "Wird gebraucht, um Tonblöcke in Leiterplattenform zu bekommen. Vermutlich das ineffizienteste Werkzeug in der Geschichte der Menschheit, da es nach einer Verwendung kaputt geht.", + "oc:tooltip.datacard0": "Stellt einige komplexe Algorithmen wie Hash-Funktionen und deflate/inflate bereit.", + "oc:tooltip.datacard1": "Stellt einige komplexe Algorithmen wie Hash-Funktionen und deflate/inflate bereit.", + "oc:tooltip.datacard2": "Stellt einige komplexe Algorithmen wie Hash-Funktionen und deflate/inflate bereit.", + "oc:tooltip.debugcard": "Kreativ-Modus-Gegenstand, erlaubt es die Welt zu manipulieren um das Testen zu erleichtern. Verwendung auf eigene Gefahr.", + "oc:tooltip.debugger": "Erlaubt, Informationen über OCs internes Netzwerk auszugeben. Nur verwenden, wenn von einem Entwickler dazu aufgefordert.", + "oc:tooltip.diamondchip": "Ein kleines Stück eines einst wunderschönen Diamanten. Er wird niemals wieder so sein, wie er war.", + "oc:tooltip.disassembler": "Zerlegt Gegenstände in ihre Einzelteile. §lWarnung§7: zurückgewonnene Gegenstände haben eine %s%%-ige Chance beim Extrahieren kaputt zu gehen!", + "oc:tooltip.disk": "Sehr einfaches Speichermedium, das verwendet werden kann, um Disketten und Festplatten zu fertigen.", + "oc:tooltip.diskdrive.CC": "ComputerCraft-Disketten werden §aauch unterstützt§7.", + "oc:tooltip.diskdrive": "Erlaubt es, Disketten zu lesen und zu beschreiben. Kann in Robotern installiert werden, um später Disketten einlegen zu können.", + "oc:tooltip.diskdrivemountable": "Funktioniert genauso wie ein normales Diskettenlaufwerk, wird aber in einem Serverschrank installiert.", + "oc:tooltip.diskusage": "Festplattennutzung: %s/%s Byte", + "oc:tooltip.disklocked": "Gesperrt von %s", + "oc:tooltip.diskmodemanaged": "Modus: Managed", + "oc:tooltip.diskmodeunmanaged": "Modus: Unmanaged", + "oc:tooltip.drone": "Drohnen sind schlichte, flinke Aufklärungseinheiten mit limitierter Inventargröße.", + "oc:tooltip.dronecase": "Dieses Gehäuse wird verwendet, um Drohnen in der Elektronik-Werkbank zu bauen. Es bietet Platz für wenige Komponenten und kommt mit endsteinbetriebener Levitation.", + "oc:tooltip.eeprom": "Kleiner, programmierbarer Speicher für das BIOS, das Computer zum starten verwenden.", + "oc:tooltip.fakeendstone": "So gut wie echt, kann sogar schweben!", + "oc:tooltip.geolyzer": "Erlaubt es die Härte der Blöcke in der Umgebung abzufragen. Hilfreich um Hologramme der Gegend zu erzeugen, oder um Erze zu entdecken.", + "oc:tooltip.graphicscard": "Erlaubt es, den angezeigten Inhalt von Bildschirmen zu ändern.\nHöchstauflösung: §f%sx%s§7\nMaximale Farbtiefe: §f%s§7\nOperationen/Tick: §f%s§7", + "oc:tooltip.hoverboots": "Spring höher, fall tiefer, geh besser. Dies und noch mehr bekommst du mit den neuen, patentierten Schwebestiefeln (TM).", + "oc:tooltip.inkcartridge": "Wird verwendet, um 3D-Drucker zu befüllen. Aus mysteriösen Gründen muss die Kartusche nicht fest im Drucker eingebaut werden.", + "oc:tooltip.inkcartridgeempty": "Diese Kartusche wurde trocken gelegt. Fülle sie mit Farben wieder auf. Oder wirf sie weg. Mir doch egal.", + "oc:tooltip.internetcard": "Diese Karte erlaubt es, HTTP-Anfragen zu senden und echte TCP-Sockets zu verwenden.", + "oc:tooltip.interweb": "Kann in einer Internetkarte verwendet werden, um Computer mit dem rechtsfreien Raum kommunizieren zu lassen.", + "oc:tooltip.ironnugget": "Ein Nugget, das aus Eisen besteht, darum wird es ja auch Eisennugget genannt, duh...", + "oc:tooltip.keyboard": "Kann an Bildschirmen befestigt werden, um auf ihnen zu tippen.", + "oc:tooltip.hologram0": "Ein Volumendisplay, das beliebige, von Computern festgelegte Voxelstrukturen anzeigt.\nAuflösung: §f48x32x48§7\nMaximale Skalierung: §f3x§7\nFarbtiefe: §fMonochrom§7", + "oc:tooltip.hologram1": "Ein Volumendisplay, das beliebige, von Computern festgelegte Voxelstrukturen anzeigt.\nAuflösung: §f48x32x48§7\nMaximale Skalierung: §f4x§7\nFarbtiefe: §fTricolor§7", + "oc:tooltip.linkedcard": "Diese Karten werden paarweise hergestellt, und können ausschließlich mit ihrer jeweilgen Partnerkarte kommunizieren, dafür allerdings über beliebige Entfernungen, und sogar über Dimensionen hinweg. Der Nachteil ist der hohe Energieverbrauch beim Senden einer Nachricht.", + "oc:tooltip.linkedcard_channel": "§8Kanal: %s§7", + "oc:tooltip.manual": "Alles, was es über OpenComputers zu wissen gibt. Und mehr. Und das alles zu dem unglaublich niedrigen Preis von... §obitte R dücken, um fortzufahren§7.", + "oc:tooltip.materialcosts": "Halte [§f%s§7] gedrückt für Materialkosten.", + "oc:tooltip.materials": "Materialien:", + "oc:tooltip.memory": "Braucht ein jeder Computer, um zu starten. Je mehr vorhanden, desto komplexere Programme können ausgeführt werden.", + "oc:tooltip.microchip": "Tritt auch unter dem Alias Integrierter Schaltkreis auf. Keine Ahnung, warum das auch mit Redstone klappt, aber es funktioniert.", + "oc:tooltip.microcontroller": "Mikrocontroller sind möglichst einfache Computer. Sie sind dazu gedacht, für Spezialfälle verwendet zu werden, bei denen sie einfach das Programm auf dem in ihnen eingebauten EEPROM ausführen sollen.", + "oc:tooltip.microcontrollercase": "Dieses Gehäuse wird verwendet, um Mikrocontroller in der Elektronik-Werkbank zu bauen. Platziere es in eine solche und füge weitere Komponenten hinzu, um einen Mikrocontroller zu erstellen.", + "oc:tooltip.motionsensor": "Kann Bewegungen sich in der Nähe befindender Lebewesen erkennen. Benötigt eine klare Sichtlinie.", + "oc:tooltip.nanomachines": "Kontrolleinheit und eine Menge Nanomaschinen zur Einnahme, sofern du dich traust.", + "oc:tooltip.networkcard": "Erlaubt es Computern, die über mehrere Blöcke miteinander verbunden sind (z.B. Kabel), mittels Netzwerknachrichten zu kommunizieren.", + "oc:tooltip.poweracceptor": "Energiewandelgeschwindigkeit: §f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§fBuildCraft MJ§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§fFactorization Charge§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fIndustrialCraft² EU§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§fMekanism Joules§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fThermal Expansion RF§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fResonant Engine Coulombs§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Wandelt Strom anderer Mods in den internen Energietyp um. Umwandlungsverhältnisse:", + "oc:tooltip.powerdistributor": "Verteilt Energie zwischen mehreren Netzwerken. Nützlich, um Energie mit einem Wandler auf mehrere Subnetze, die voneinander getrennt sein sollen, zu verteilen.", + "oc:tooltip.present": "... für deine Mühen. Öffne dieses Geschenk für eine Chance, §kdolle Dinge§7 zu erhalten!\n§8Fertige OpenComputers-Gegenstände zur rechten Zeit, und du hast die Chance ein Geschenk zu erhalten.§7", + "oc:tooltip.print.BeaconBase": "§8Funktioniert als Grundstein für ein Leuchtfeuer.", + "oc:tooltip.print.LightValue": "§8Leuchtkraft: %s.", + "oc:tooltip.print.RedstoneLevel": "§8Redstone-Signalstärke: %s.", + "oc:tooltip.printedcircuitboard": "Hierauf basieren alle Erweiterungskarten, Speicher und so weiter.", + "oc:tooltip.printer": "Erlaubt es, Blöcke aus benutzerdefinierten Formen zu drucken. Verwendet Chamälium und Tintenkartuschen. Muss über einen Computer konfiguriert werden. Von Kindern fern halten. Weil halt.", + "oc:tooltip.raid": "Erlaubt es, drei Festplatten zu einem größeren Dateisystem zusammenzuschließen, welches von allen verbundenen Computern genutzt werden kann.", + "oc:tooltip.rawcircuitboard": "Kann in einer Ofen-kompatiblen Schmelze freier Wahl gehärtet werden.", + "oc:tooltip.redstone": "Erlaubt das Lesen und Ausgeben von Redstonesignalen um den Block herum. Kann von jedem Computer, der mit dem Block verbunden ist, gesteuert werden. Dieser Block ist quasi wie eine externe Redstonekarte.", + "oc:tooltip.redstonecard.ProjectRed": "§fProjectRed§7 wird §aunterstützt§7.", + "oc:tooltip.redstonecard.RedLogic": "§fRedLogic§7 wird §aunterstützt§7.", + "oc:tooltip.redstonecard.RedNet": "§fRedNet§7 wird §aunterstützt§7.", + "oc:tooltip.redstonecard.WirelessCBE": "§fWireless Redstone (ChickenBones)§7 wird §aunterstützt§7.", + "oc:tooltip.redstonecard.WirelessSV": "§fWireless Redstone (SlimeVoid)§7 wird §aunterstützt§7.", + "oc:tooltip.redstonecard": "Erlaubt das Lesen und Ausgeben von Redstonesignalen um den Computer oder Roboter herum.", + "oc:tooltip.relay": "Erlaubt es, mehrere Netzwerke miteinander zu verbinden. Leitet ausschließlich Netzwerknachrichten weiter, Komponenten \"hinter\" dem Switch sind nicht sichtbar. Nützlich, um Netzwerke zu trennen, jedoch nach wie vor Kommunikation zwischen den Netzwerken zu erlauben, z.b. mittels Netzwerkkarten.", + "oc:tooltip.robot": "Im Gegensatz zu normalen Computern können sich Roboter in der Welt bewegen und ähnlich wie Spieler mit der Welt interagieren. Sie können jedoch §onicht§r§7 mit externen Komponenten interagieren!", + "oc:tooltip.robot_level": "§fStufe§7: §a%s§7.", + "oc:tooltip.robot_storedenergy": "§fGespeicherte Energie§7: §a%s§7.", + "oc:tooltip.screen": "Zeigt Text an, gesteuert von Grafikkarten in Computern.\nHöchstauflösung: §f%sx%s§7\nMaximale Farbtiefe: §f%s§7", + "oc:tooltip.server": "Ein Server kann wie ein gewöhnliches Computergehäuse mit Komponenten verbessert werden. Um den Server zu starten, muss er in einem Servergehäuse installiert werden.", + "oc:tooltip.server.Components": "Installierte Komponenten:", + "oc:tooltip.rack": "Erlaubt die Installation von bis zu vier Servern oder anderen Serverschrankkomponenten.", + "oc:tooltip.switch": "Erlaubt es, mehrere Netzwerke miteinander zu verbinden. Leitet ausschließlich Netzwerknachrichten weiter, Komponenten \"hinter\" dem Switch sind nicht sichtbar. Nützlich, um Netzwerke zu trennen, jedoch nach wie vor Kommunikation zwischen den Netzwerken zu erlauben, z.B. mittels Netzwerkkarten.", + "oc:tooltip.tablet": "Ein Tablet-PC, für Lua unterwegs. Kann durch Sneak-Aktivierung zwangsgestoppt werden.", + "oc:tooltip.tabletcase": "Einfaches Gehäuse für Tablet-PCs. Kann in der Elektronik-Werkbank mit Komponenten bestückt werden, um einen Tablet-PC zu fertigen.", + "oc:tooltip.terminal": "Erlaubt es, einen Server aus der Ferne zu steuern, so lange man sich in Reichweite des Servers befindet. Verhält sich wie Bildschirm und Tastatur in einem. Kann mit Shift-Rechtsklick an einen Server in einem Serverschrank gebunden werden.", + "oc:tooltip.terminalserver": "Das Rückgrat für Fernzugriff. Fernbedienungen können hiermit verbunden werden. Enthält virtuelle Tastatur und Bildschirm.", + "oc:tooltip.texturepicker": "Dieses Werkzeug erlaubt es, eine Zeichenkette anzuzeigen, die die Oberfläche eines Blocks beschreibt und in Form-Definitionen für 3D-Drucker verwendet werden kann. Definiv keine Texturnamen, oh nein. Nix da.", + "oc:tooltip.tier": "§8Stufe %s", + "oc:tooltip.netsplitter": "Kann Netzwerke dynamisch verbinden. Die Konnektivität jeder Seite kann umgeschaltet werden, in dem man \"Professionelle Wartungsarbeiten\" mit einem Schraubenschlüssel durchführt. Sie kann auch mit einem Redstone-Signal an entsprechenden Seiten invertiert werden.", + "oc:tooltip.toolong": "Halte [§f%s§7] gedrückt für mehr Infos.", + "oc:tooltip.transistor": "Elementarer Baustein der meisten Computerkomponenten. Nicht zu verwechseln mit Steinelementaren.", + "oc:tooltip.transposer": "Ermöglicht automatischen Transfer von Items und Flüssigkeiten zwischen angrenzenden Blöcken.", + "oc:tooltip.upgradeangel": "Erlaubt es Robotern, Blöcke in die Luft zu setzen, selbst wenn kein Referenzblock daneben existiert.", + "oc:tooltip.upgradebattery": "Erhöht die Energiespeicherkapazität eines Roboters, was ihm erlaubt, länger zu arbeiten, ohne erneut aufgeladen werden zu müssen.\nKapazität: §f%s§7", + "oc:tooltip.upgradechunkloader": "Wenn sich im Wald ein Roboter bewegt, und niemand da ist, ihn zu sehen, bewegt er sich dann wirklich? Dieses Upgrade stellt sicher, dass dem so ist. Es hält den Chunk, in dem sich der Roboter befindet, geladen, verbraucht jedoch Energie, während es aktiv ist.", + "oc:tooltip.upgradecontainercard": "Dieses Behälter-Upgrade erlaubt es, eine Karte in einem bereits zusammengebauten Roboter zu installieren und wieder zu entfernen.\nMaximale Stufe: §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "Dieses Behälter-Upgrade erlaubt es, ein Upgrade in einem bereits zusammengebauten Roboter zu installieren und wieder zu entfernen.\nMaximale Stufe: §f%s§7", + "oc:tooltip.upgradecrafting": "Ermöglicht Robotern, in dem oberen linken Bereich ihres Inventars Dinge zu fertigen. Gegenstände müssen so angeordnet sein, wie sie es in einer Werkbank wären.", + "oc:tooltip.upgradedatabase": "Diese Upgrade erlaubt es, Gegenstandsinformationen - für spätere Verwendung in anderen Komponenten - zu speichern.\nMaximale Einträge: §f%s§7", + "oc:tooltip.upgradeexperience": "Dieses Upgrade erlaubt es Robotern, durch verschiedene Aktionen Erfahrung zu sammeln. Je mehr Erfahrung ein Roboter hat, desto mehr Energie kann er speichern, desto schneller kann er Blöcke abbauen und desto effizienter kann er mit Werkzeugen umgehen.", + "oc:tooltip.upgradegenerator": "Kann verwendet werden, um unterwegs Energie aus Brennstoffen zu erzeugen. Verbraucht Gegenstände über einen ihrem Brennwert gemäßen Zeitraum.\n§fEffizienz§7: §a%s%%§7", + "oc:tooltip.upgradehover": "Erlaubt Robotern höher zu fliegen, ohne an Wänden klettern zu müssen.\nMaximalhöhe: §f%s§7", + "oc:tooltip.upgradeinventory": "Dieses Upgrade gibt Robotern ein internes Inventar. Ohne ein solches Upgrade können Roboter keine Gegenstände verwahren.", + "oc:tooltip.upgradeinventorycontroller": "Dieses Upgrade erlaubt es dem Roboter, präziser mit externen Inventaren zu interagieren, und erlaubt es ihm, das angelegte Werkzeug mit einem Gegenstand in seinem Inventar auszutauschen.", + "oc:tooltip.upgrademf": "Erlaubt es Adaptern, mit Blöcken zu interagieren, die etwas weiter weg sind.", + "oc:tooltip.upgrademf.Linked": "§fVerbindung hergestellt§7", + "oc:tooltip.upgrademf.Unlinked": "§fKeine Verbindung§7", + "oc:tooltip.upgradeleash": "Erlaubt es manchen Geräten, wie etwa Drohnen, B- *getuschel* Verzeihung. Mir wurde soeben zugetragen, dass es tatsächlich dazu verwendet werden kann, Tiere an die Leine zu legen. Sogar viele Viecher.", + "oc:tooltip.upgradenavigation": "Erlaubt es Robotern, ihre Position und Ausrichtung zu bestimmen. Die Position ist relativ zur Mitte der Karte, die in diesem Upgrade verbaut wurde.", + "oc:tooltip.upgradepiston": "Dieses Upgrade ist sehr drückend. Es macht es möglich Blöcke zu verschieben, ähnlich dem Kolben. Es kann jedoch §lkeine§7 Entities bewegen.", + "oc:tooltip.upgradesign": "Erlaubt das Lesen und Schreiben von Text auf Schildern.", + "oc:tooltip.upgradesolargenerator": "Kann verwendet werden, um unterwegs Energie aus Sonnenlicht zu generieren. Benötigt eine ungehinderte Sicht zum Himmel über dem Roboter. Generiert Energie mit %s%% der Geschwindigkeit eines Stirlingmotors.", + "oc:tooltip.upgradetank": "Dieses Upgrade gibt Robotern einen internen Tank. Ohne ein solches Upgrade können Roboter keine Flüssigkeiten verwahren.", + "oc:tooltip.upgradetankcontroller": "Dieses Upgrade erlaubt es dem Roboter, präziser mit externen Tanks zu interagieren, und erlaubt es ihm, Flüssigkeiten in und aus sich im Inventar befindlichen Tank-Gegenständen zu pumpen.", + "oc:tooltip.upgradetractorbeam": "Stattet den Roboter mit unglaublich fortschrittlicher Technologie - Kosename: \"Gegenstandsmagnet\" - aus. Erlaubt es dem Roboter, Gegenstände, innerhalb von 3 Blöcken um sich herum, einzusammeln.", + "oc:tooltip.waypoint": "Ein Orientierungpunkt für Geräte mit einem Navigations-Upgrade.", + "oc:tooltip.wirelessnetworkcard": "Erlaubt das drahtlose Senden von Netzwerknachrichten, zusätzlich zu normalen. Drahtlose Nachrichten werden nur gesendet, wenn eine §fSignalstärke§7 festgelegt wurde!", + "oc:tooltip.worldsensorcard": "Erlaubt es, Informationen über die Welt auszulesen, wie etwa Gravitation und ob die Atmosphäre atembar ist. Verwendung von Messergebnissen auf eigene Gefahr. Der Hersteller übernimmt keinerlei Garantie.", + "oc:tooltip.wrench": "Eine Mischung aus Schraubenzieher und Schraubenschlüssel, einfach zu benutzen, aber schwer zu meistern.", + "achievement.oc.adapter": "Steck mich ein", + "achievement.oc.adapter.desc": "Interagiert mit Blöcken aus anderen Mods, und sogar Vanilla-Minecraft!", + "achievement.oc.assembler": "Wundervoll", + "achievement.oc.assembler.desc": "Zeit, die Welt zu erobern!", + "achievement.oc.cable": "Kein gewöhnliches Kabel", + "achievement.oc.cable.desc": "Mit patentierter Anti-Kabelsalat-Technologie.", + "achievement.oc.capacitor": "Batterien enthalten", + "achievement.oc.capacitor.desc": "Achtung: Kurzschlussgefahr.", + "achievement.oc.card": "Wir akzeptieren Karten", + "achievement.oc.card.desc": "Dreimal falsche PIN-Eingabe. Karte wird einbehalten.", + "achievement.oc.case": "Desktop-Computer", + "achievement.oc.case.desc": "Desktop (und Betriebssystem) separat erhältlich.", + "achievement.oc.charger": "Die Spannung steigt", + "achievement.oc.charger.desc": "Und auflad- verdammt, schon wieder das Redstone-Signal vergessen.", + "achievement.oc.chip": "Technischer Fortschritt", + "achievement.oc.chip.desc": "Besser als Elekrtonenröhren.", + "achievement.oc.cpu": "Übertaktet", + "achievement.oc.cpu.desc": "Endlich ein Nutzen für die ungenutzten Prozessorzyklen.", + "achievement.oc.disassembler": "Nochmal von vorn", + "achievement.oc.disassembler.desc": "Falls deine brillianten Ideen am Ende doch nicht so brilliant sind.", + "achievement.oc.diskDrive": "*klick brumm brumm brumm ratter*", + "achievement.oc.diskDrive.desc": "Weniger Speicherplatz, aber welch ein wundervolles Geräusch.", + "achievement.oc.drone": "Startbereit", + "achievement.oc.drone.desc": "Keep calm and nuke it from orbit.", + "achievement.oc.eeprom": "Es kann nur einen geben", + "achievement.oc.eeprom.desc": "Pro Computer, genau genommen. Für eine deterministische Boot-Reihenfolge, weißt du?", + "achievement.oc.floppy": "Der Eine Ri- Datenspeicher", + "achievement.oc.floppy.desc": "Nicht zu verwechseln mit Flappy.", + "achievement.oc.geolyzer": "Gezielte Rohstoffsuche", + "achievement.oc.geolyzer.desc": "Umweltfreundlicher als Fracking, versprochen.", + "achievement.oc.graphicsCard": "LastGen", + "achievement.oc.graphicsCard.desc": "The way it's meant to be... äh... rendered. Ja. So ungefähr.", + "achievement.oc.hdd": "Hotdog-Dealer", + "achievement.oc.hdd.desc": "Moment, das stimmt nicht ganz. Warte, gleich hab' ich's...", + "achievement.oc.hologram": "Eine höhere Dimension", + "achievement.oc.hologram.desc": "Weil 2D so langweilig ist. Oder ist es das wirklich?", + "achievement.oc.keyboard": "SchmutzFänger3000", + "achievement.oc.keyboard.desc": "Es wird davon abgeraten, sie umzudrehen und zu schütteln, auch wenn es noch so verlockend ist.", + "achievement.oc.microcontroller": "Kleine Schwester", + "achievement.oc.microcontroller.desc": "Das kleine Geschwisterkind des Computers.", + "achievement.oc.motionSensor": "Got the Moves", + "achievement.oc.motionSensor.desc": "Like Steve Swagger.", + "achievement.oc.networkCard": "Fernleitung", + "achievement.oc.networkCard.desc": "Perfekt um diese transitiven Beziehungen aufrecht zu erhalten.", + "achievement.oc.openOS": "Boot", + "achievement.oc.openOS.desc": "Das Eine Betrieb- wie, was meinst du, der Witz wird alt?", + "achievement.oc.powerDistributor": "Strom-Sharing", + "achievement.oc.powerDistributor.desc": "ElektroVZ ist so 2010.", + "achievement.oc.rack": "Multifunktionsschrank", + "achievement.oc.rack.desc": "Wird unter Anderem in Kantinen genutzt, um gebrauchte Tabletts zu sammeln.", + "achievement.oc.raid": "Suche Team", + "achievement.oc.raid.desc": "Heroic plzkthx.", + "achievement.oc.ram": "Random Access Memories", + "achievement.oc.ram.desc": "Congratulations, you're Doin' It Right.", + "achievement.oc.redstoneCard": "Kontakt", + "achievement.oc.redstoneCard.desc": "Zeit für analoge Signale.", + "achievement.oc.redstoneIO": "Außenseiter", + "achievement.oc.redstoneIO.desc": "Redstone-Signale, dort wo du sie brauchst.", + "achievement.oc.robot": "Beep Boop", + "achievement.oc.robot.desc": "VERNICHTEN!", + "achievement.oc.screen": "Hast du schon versucht, ihn aus- und wieder anzuschalten?", + "achievement.oc.screen.desc": "Nein, ernsthaft. Ein Redstone-Impuls kann wirklich einen Bildschirm an- und ausschalten.", + "achievement.oc.server": "Dediziert", + "achievement.oc.server.desc": "Hier kommen die Cloud-Dienste.", + "achievement.oc.switch": "Paketdienst", + "achievement.oc.switch.desc": "Nicht für Hinkelsteine verwenden, die könnten sonst beim Aussortieren verloren gehen.", + "achievement.oc.tablet": "Verschluckbare Kleinteile", + "achievement.oc.tablet.desc": "Von Kindern fernhalten, um unerwünschte Kreditkartenbelastungen zu vermeiden.", + "achievement.oc.transistor": "Schöne Grüße an Red!", + "achievement.oc.transistor.desc": "Jetzt kannst du dir den Soundtrack anhören.", + "achievement.oc.wirelessNetworkCard": "Das WLAN - Unendliche Weiten", + "achievement.oc.wirelessNetworkCard.desc": "Netzwerke, die nie ein Paket zuvor gesehen hat.", + "death.attack.oc.nanomachinesOverload.1": "%s ist zu gierig geworden.", + "death.attack.oc.nanomachinesOverload.2": "%s erlitt einen Nervenzusammenbruch.", + "death.attack.oc.nanomachinesOverload.3": "Die Nanomaschinen von %s gerieten wohl außer Kontrolle. Ups.", + "death.attack.oc.nanomachinesHungry.1": "%s wurde von Nanomaschinen verspeist.", + "death.attack.oc.nanomachinesHungry.2": "%s hat wohl seine Nanomaschinen nicht gefüttert.", + "death.attack.oc.nanomachinesHungry.3": "%s wurde verdaut.", + "nei.options.inventory.oredict": "OreDictionary-Namen anzeigen", + "nei.options.inventory.oredict.true": "True", + "nei.options.inventory.oredict.false": "False", + "nei.usage.oc.Manual": "Handbuch öffnen", + "option.oc.address": "Adresse", + "option.oc.componentName": "Komponentenname", + "option.oc.energy": "Energie" +} diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang deleted file mode 100644 index 67527659fa..0000000000 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ /dev/null @@ -1,484 +0,0 @@ -# This is the english master file for localizations. It will always be the most -# up-to-date version, so other localizations should be based on this one. -# Use [nl] to for a line break. - -# Blocks -tile.oc.adapter.name=Adapter -tile.oc.assembler.name=Electronics Assembler -tile.oc.cable.name=Cable -tile.oc.capacitor.name=Capacitor -tile.oc.carpetedcapacitor.name=Carpeted Capacitor -tile.oc.case1.name=Computer Case (Tier 1) -tile.oc.case2.name=Computer Case (Tier 2) -tile.oc.case3.name=Computer Case (Tier 3) -tile.oc.casecreative.name=Computer Case (Creative) -tile.oc.chameliumblock.name=Block of Chamelium -tile.oc.charger.name=Charger -tile.oc.disassembler.name=Disassembler -tile.oc.diskdrive.name=Disk Drive -tile.oc.endstone.name=End Stone -tile.oc.geolyzer.name=Geolyzer -tile.oc.hologram1.name=Hologram Projector (Tier 1) -tile.oc.hologram2.name=Hologram Projector (Tier 2) -tile.oc.keyboard.name=Keyboard -tile.oc.microcontroller.name=Microcontroller -tile.oc.motionsensor.name=Motion Sensor -tile.oc.netsplitter.name=Net Splitter -tile.oc.powerconverter.name=Power Converter -tile.oc.powerdistributor.name=Power Distributor -tile.oc.print.name=3D Print -tile.oc.printer.name=3D Printer -tile.oc.raid.name=Raid -tile.oc.redstone.name=Redstone I/O -tile.oc.relay.name=Relay -tile.oc.robot.name=Robot -tile.oc.robotafterimage.name=Robot -tile.oc.screen1.name=Screen (Tier 1) -tile.oc.screen2.name=Screen (Tier 2) -tile.oc.screen3.name=Screen (Tier 3) -tile.oc.rack.name=Rack -tile.oc.transposer.name=Transposer -tile.oc.waypoint.name=Waypoint - -# Items -item.oc.abstractbuscard.name=Abstract Bus Card -item.oc.acid.name=Grog -item.oc.alu.name=Arithmetic Logic Unit (ALU) -item.oc.analyzer.name=Analyzer -item.oc.apu0.name=Accelerated Processing Unit (APU) (Tier 2) -item.oc.apu1.name=Accelerated Processing Unit (APU) (Tier 3) -item.oc.apu2.name=Accelerated Processing Unit (APU) (Creative) -item.oc.arrowkeys.name=Arrow Keys -item.oc.buttongroup.name=Button Group -item.oc.cardbase.name=Card Base -item.oc.chamelium.name=Chamelium -item.oc.circuitboard.name=Circuit Board -item.oc.componentbus0.name=Component Bus (Tier 1) -item.oc.componentbus1.name=Component Bus (Tier 2) -item.oc.componentbus2.name=Component Bus (Tier 3) -item.oc.componentbus3.name=Component Bus (Creative) -item.oc.controlunit.name=Control Unit (CU) -item.oc.cpu0.name=Central Processing Unit (CPU) (Tier 1) -item.oc.cpu1.name=Central Processing Unit (CPU) (Tier 2) -item.oc.cpu2.name=Central Processing Unit (CPU) (Tier 3) -item.oc.cuttingwire.name=Cutting Wire -item.oc.datacard0.name=Data Card (Tier 1) -item.oc.datacard1.name=Data Card (Tier 2) -item.oc.datacard2.name=Data Card (Tier 3) -item.oc.debugcard.name=Debug Card -item.oc.debugger.name=Network Debugger -item.oc.diamondchip.name=Diamond Chip -item.oc.disk.name=Disk Platter -item.oc.diskdrivemountable.name=Disk Drive -item.oc.drone.name=Drone -item.oc.dronecase0.name=Drone Case (Tier 1) -item.oc.dronecase1.name=Drone Case (Tier 2) -item.oc.dronecase3.name=Drone Case (Creative) -item.oc.eeprom.name=EEPROM -item.oc.floppydisk.name=Floppy Disk -item.oc.graphicscard0.name=Graphics Card (Tier 1) -item.oc.graphicscard1.name=Graphics Card (Tier 2) -item.oc.graphicscard2.name=Graphics Card (Tier 3) -item.oc.harddiskdrive0.name=Hard Disk Drive (Tier 1) -item.oc.harddiskdrive1.name=Hard Disk Drive (Tier 2) -item.oc.harddiskdrive2.name=Hard Disk Drive (Tier 3) -item.oc.hoverboots.name=Hover Boots -item.oc.inkcartridge.name=Ink Cartridge -item.oc.inkcartridgeempty.name=Ink Cartridge (Empty) -item.oc.internetcard.name=Internet Card -item.oc.interweb.name=Interweb -item.oc.ironnugget.name=Iron Nugget -item.oc.linkedcard.name=Linked Card -item.oc.manual.name=OpenComputers Manual -item.oc.memory0.name=Memory (Tier 1) -item.oc.memory1.name=Memory (Tier 1.5) -item.oc.memory2.name=Memory (Tier 2) -item.oc.memory3.name=Memory (Tier 2.5) -item.oc.memory4.name=Memory (Tier 3) -item.oc.memory5.name=Memory (Tier 3.5) -item.oc.microchip0.name=Microchip (Tier 1) -item.oc.microchip1.name=Microchip (Tier 2) -item.oc.microchip2.name=Microchip (Tier 3) -item.oc.microcontrollercase0.name=Microcontroller Case (Tier 1) -item.oc.microcontrollercase1.name=Microcontroller Case (Tier 2) -item.oc.microcontrollercase3.name=Microcontroller Case (Creative) -item.oc.nanomachines.name=Nanomachines -item.oc.networkcard.name=Network Card -item.oc.numpad.name=Numeric Keypad -item.oc.present.name=A little something... -item.oc.printedcircuitboard.name=Printed Circuit Board (PCB) -item.oc.rawcircuitboard.name=Raw Circuit Board -item.oc.redstonecard0.name=Redstone Card (Tier 1) -item.oc.redstonecard1.name=Redstone Card (Tier 2) -item.oc.server0.name=Server (Tier 1) -item.oc.server1.name=Server (Tier 2) -item.oc.server2.name=Server (Tier 3) -item.oc.server3.name=Server (Creative) -item.oc.tablet.name=Tablet -item.oc.tabletcase0.name=Tablet Case (Tier 1) -item.oc.tabletcase1.name=Tablet Case (Tier 2) -item.oc.tabletcase3.name=Tablet Case (Creative) -item.oc.terminal.name=Remote Terminal -item.oc.terminalserver.name=Terminal Server -item.oc.texturepicker.name=Texture Picker -item.oc.transistor.name=Transistor -item.oc.upgradeangel.name=Angel Upgrade -item.oc.upgradebattery0.name=Battery Upgrade (Tier 1) -item.oc.upgradebattery1.name=Battery Upgrade (Tier 2) -item.oc.upgradebattery2.name=Battery Upgrade (Tier 3) -item.oc.upgradechunkloader.name=Chunkloader Upgrade -item.oc.upgradecontainercard0.name=Card Container (Tier 1) -item.oc.upgradecontainercard1.name=Card Container (Tier 2) -item.oc.upgradecontainercard2.name=Card Container (Tier 3) -item.oc.upgradecontainerupgrade0.name=Upgrade Container (Tier 1) -item.oc.upgradecontainerupgrade1.name=Upgrade Container (Tier 2) -item.oc.upgradecontainerupgrade2.name=Upgrade Container (Tier 3) -item.oc.upgradecrafting.name=Crafting Upgrade -item.oc.upgradedatabase0.name=Database Upgrade (Tier 1) -item.oc.upgradedatabase1.name=Database Upgrade (Tier 2) -item.oc.upgradedatabase2.name=Database Upgrade (Tier 3) -item.oc.upgradeexperience.name=Experience Upgrade -item.oc.upgradegenerator.name=Generator Upgrade -item.oc.upgradehover0.name=Hover Upgrade (Tier 1) -item.oc.upgradehover1.name=Hover Upgrade (Tier 2) -item.oc.upgradeinventory.name=Inventory Upgrade -item.oc.upgradeinventorycontroller.name=Inventory Controller Upgrade -item.oc.upgradeleash.name=Leash Upgrade -item.oc.upgrademf.name=MFU -item.oc.upgradenavigation.name=Navigation Upgrade -item.oc.upgradepiston.name=Piston Upgrade -item.oc.upgradestickypiston.name=Sticky Piston Upgrade -item.oc.upgradesign.name=Sign I/O Upgrade -item.oc.upgradesolargenerator.name=Solar Generator Upgrade -item.oc.upgradetank.name=Tank Upgrade -item.oc.upgradetankcontroller.name=Tank Controller Upgrade -item.oc.upgradetractorbeam.name=Tractor Beam Upgrade -item.oc.upgradetrading.name=Trading Upgrade -item.oc.wirelessnetworkcard0.name=Wireless Network Card (Tier 1) -item.oc.wirelessnetworkcard1.name=Wireless Network Card (Tier 2) -item.oc.worldsensorcard.name=World Sensor Card -item.oc.wrench.name=Scrench - -# Entities -entity.oc.Drone.name=Drone - -# GUI -oc:gui.Analyzer.Address=§6Address§f: %s -oc:gui.Analyzer.AddressCopied=Address copied to clipboard. -oc:gui.Analyzer.ChargerSpeed=§6Charge speed§f: %s -oc:gui.Analyzer.ComponentName=§6Component name§f: %s -oc:gui.Analyzer.Components=§6Number of connected components§f: %s -oc:gui.Analyzer.CopyToClipboard=Click to copy to clipboard. -oc:gui.Analyzer.LastError=§6Last error§f: %s -oc:gui.Analyzer.RobotName=§6Name§f: %s -oc:gui.Analyzer.RobotOwner=§6Owner§f: %s -oc:gui.Analyzer.RobotXp=§6Experience§f: %s (Level %s) -oc:gui.Analyzer.StoredEnergy=§6Stored energy§f: %s -oc:gui.Analyzer.TotalEnergy=§6Total stored energy§f: %s -oc:gui.Analyzer.Users=§6Users§f: %s -oc:gui.Analyzer.WirelessStrength=§6Signal strength§f: %s -oc:gui.Assembler.Collect=Collect output -oc:gui.Assembler.Complexity=Complexity: %s/%s -oc:gui.Assembler.InsertCase=Insert a base part -oc:gui.Assembler.InsertCPU=Insert a CPU -oc:gui.Assembler.InsertRAM=Insert some RAM -oc:gui.Assembler.Progress=Progress: %s%% (%s) -oc:gui.Assembler.Run=Assemble -oc:gui.Assembler.Warning.BIOS=BIOS -oc:gui.Assembler.Warning.GraphicsCard=Graphics Card -oc:gui.Assembler.Warning.Inventory=Inventory Upgrade -oc:gui.Assembler.Warning.Keyboard=Keyboard -oc:gui.Assembler.Warning.OS=Bootable Medium -oc:gui.Assembler.Warning.Screen=Screen -oc:gui.Assembler.Warnings=§eWarning§7: Recommended components are missing. -oc:gui.Chat.NewVersion=A new version is available: %s -oc:gui.Chat.TextureName=§7Texture name is §a%s§f. -oc:gui.Chat.WarningClassTransformer=There were §cerrors§f running the class transformer. Please report this, together with your (full!) FML §alatest.log§f/§afml-server-latest.log§f logfile, thank you! -oc:gui.Chat.WarningFingerprint=§cWARNING§f - fingerprint mismatch! Expected '§a%s§f' but got '§e%s§f'. Unless you are a modder and are running the deobfuscated version of the mod, it is §lstrongly§f recommended to redownload OpenComputers, because the JAR you are using may have been tampered with. -oc:gui.Chat.WarningLink=Could not open link: %s -oc:gui.Chat.WarningLuaFallback=Native Lua libraries are not available, computers will not be able to persist their state. They will reboot on chunk reloads. -oc:gui.Chat.WarningProjectRed=You are using a version of Project: Red that is incompatible with OpenComputers. Try updating your version of Project: Red. -oc:gui.Chat.WarningRecipes=There were errors loading one or more recipes. Some items may be uncraftable. Please check your log file for more information. -oc:gui.Chat.WarningSimpleComponent=An addon (yours?) using the §aSimpleComponent§f interface did §esomething wrong§f. Component logic could not be injected. Please check your log file for more information. -oc:gui.Drive.Managed=Managed -oc:gui.Drive.Unmanaged=Unmanaged -oc:gui.Drive.ReadOnlyLock=Lock -oc:gui.Drive.ReadOnlyLockWarning=§lRead Only§r lock. Cannot be removed unless the drive is wiped. -oc:gui.Drive.Warning=§lWarning§r: switching modes will result in a loss of all data currently stored on the disk! -oc:gui.Error.ComponentOverflow=Too many components connected to the computer. -oc:gui.Error.InternalError=Internal error, please see the log file. This is probably a bug. -oc:gui.Error.NoCPU=No CPU is installed in the computer. -oc:gui.Error.NoEnergy=Not enough energy. -oc:gui.Error.NoRAM=No RAM is installed in the computer. -oc:gui.Error.OutOfMemory=Out of memory. -oc:gui.Manual.Blocks=OpenComputers Blocks -oc:gui.Manual.Home=Home -oc:gui.Manual.Items=OpenComputers Items -oc:gui.Manual.Warning.BlockMissing=Block unavailable. -oc:gui.Manual.Warning.ImageMissing=Image not found. -oc:gui.Manual.Warning.ItemMissing=Item unavailable. -oc:gui.Manual.Warning.OreDictMissing=Ore dictionary entry unavailable. -oc:gui.Raid.Warning=§4Adding a disk wipes it.[nl] Removing a disk wipes the raid. -oc:gui.Robot.Power=Energy -oc:gui.Robot.TurnOff=Turn off -oc:gui.Robot.TurnOn=Turn on[nl]§7Use an Analyzer to troubleshoot errors.§r -oc:gui.Rack.Back=Back -oc:gui.Rack.Bottom=Bottom -oc:gui.Rack.Left=Left -oc:gui.Rack.None=None -oc:gui.Rack.Right=Right -oc:gui.Rack.Enabled=Enabled -oc:gui.Rack.Disabled=Disabled -oc:gui.Rack.RelayModeTooltip=Relay Mode -oc:gui.Rack.Top=Top -oc:gui.Switch.PacketsPerCycle=Packets / cycle -oc:gui.Switch.QueueSize=Queue size -oc:gui.Switch.TransferRate=Cycle rate -oc:gui.Terminal.InvalidKey=Invalid key, most likely another terminal has been bound to the server. -oc:gui.Terminal.OutOfRange=No signal. - -# Containers -oc:container.adapter=Adapter -oc:container.case=Computer -oc:container.charger=Charger -oc:container.disassembler=Disassembler -oc:container.diskdrive=Disk Drive -oc:container.printer=Printer -oc:container.raid=Raid -oc:container.relay=Relay -oc:container.server=Server -oc:container.rack=Rack -oc:container.tabletwrapper=Tablet - -# Keybinds -key.clipboardPaste=Paste Clipboard - -# Item / Block Tooltips -oc:tooltip.abstractbuscard=Allows interacting with §fStargateTech 2§7's abstract bus by sending and receiving LIP packets. -oc:tooltip.acid=A highly toxic pseudo-liquid, usually only consumed by certain pirates. May prove to be useful in other ways, too, however. -oc:tooltip.adapter=Used to control non-component blocks, such as vanilla blocks or blocks from other mods. -oc:tooltip.alu=Adds numbers so you don't have to. It might be better this way. -oc:tooltip.analyzer=Used to display information about blocks, such as their §faddress§7 and §fcomponent name§7.[nl] Also displays the error that caused a computer to crash if it did not shut down normally. -oc:tooltip.apu=This is a CPU with an integrated GPU (or IGP), when you just need that extra card slot.[nl] Supported components: §f%s§7[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7 -oc:tooltip.assembler=Allows constructing robots and other devices from a number of different computer parts. -oc:tooltip.cable=A cheap way of connecting blocks. -oc:tooltip.capacitor=Stores energy for later use. Can be filled and emptied very quickly. -oc:tooltip.carpetedcapacitor=Stores energy for later use. Can be filled and emptied very quickly. Charges when Sheep or Ocelots walk on it -oc:tooltip.cardbase=As the name indicates, this is the basic building block for all expansion cards. -oc:tooltip.case=The Computer Case is the basic building block for computers and houses the computer's §fextension cards§7, §fRAM§7 and §fhard disks§7.[nl] Slots: §f%s§7 -oc:tooltip.chamelium=Raw material for 3D prints. Do not swallow: may lead to blindness and temporary lack of presence. -oc:tooltip.chameliumblock=Nice and clean. Handy for tinted shapes in 3D prints, or just for having a clean, colored block to decorate your fancy base with. -oc:tooltip.charger=Transfers energy from capacitors into adjacent robots and drones. The transfer rate depends on the incoming §fredstone signal§7, where no signal means don't charge devices, and maximum strength means charge at full speed. Can also be used to charge tablets and access hard drives in tablets. -oc:tooltip.circuitboard=Now we're getting somewhere. Can be etched to obtain a printed circuit board. -oc:tooltip.controlunit=This is the unit that... controls... stuff. You need it to build a CPU. So yeah, totally important. -oc:tooltip.componentbus=This expansion allows servers to communicate with more components at the same time, similar to how CPUs do.[nl] Supported components: §f%s§7 -oc:tooltip.cpu=An essential component of all computers. The clock rate is a bit unreliable, but what do you expect when it runs on a pocket sundial?[nl] Supported components: §f%s§7 -oc:tooltip.cpu.Architecture=Architecture: §f%s§7 -oc:tooltip.cuttingwire=Used to cut clay blocks into circuit board shape. Breaks after one use, which probably makes it the most inefficient tool ever. -oc:tooltip.datacard0=Provides a couple of advanced algorithms such as hashing and deflate/inflate. -oc:tooltip.datacard1=Provides a couple of advanced algorithms such as hashing, AES encryption and deflate/inflate. -oc:tooltip.datacard2=Provides a couple of advanced algorithms such as hashing, AES encryption, elliptic curve cryptography and deflate/inflate. -oc:tooltip.debugcard=Creative mode item, allows manipulating the world to make testing easier. Use at your own peril. -oc:tooltip.debugger=Can be used to output debug information on OC's internal network grid. Only use if so instructed by a dev. -oc:tooltip.diamondchip=A small piece of a once radiant diamond. It will never be the same again. -oc:tooltip.disassembler=Separates items into their original components. §lWarning§7: returned items have a %s%% chance of breaking in the process! -oc:tooltip.disk=Primitive medium that can be used to build persistent storage devices. -oc:tooltip.diskdrive.CC=ComputerCraft floppies are §asupported§7. -oc:tooltip.diskdrive=Allows reading and writing floppies. Can be installed in robots to allow inserting floppies later on. -oc:tooltip.diskdrivemountable=Provides the same functionality as a normal disk drive, but must be installed in a rack. -oc:tooltip.diskusage=Disk usage: %s/%s Byte -oc:tooltip.disklocked=Locked by: %s -oc:tooltip.diskmodemanaged=Mode: Managed -oc:tooltip.diskmodeunmanaged=Mode: Unmanaged -oc:tooltip.drone=Drones are light-weight, fast reconnaissance units with limited cargo space. -oc:tooltip.dronecase=This casing is used to build Drones in the assembler. It has room for a small amount of components and provides endstone-powered levitation. -oc:tooltip.eeprom=Small, programmable storage that contains the BIOS computers use to boot. -oc:tooltip.fakeendstone=Almost as good as the real thing, even emulates its floatiness! -oc:tooltip.geolyzer=Allows scanning the surrounding area's blocks' hardness. This information can be useful for generating holograms of the area or for detecting ores. -oc:tooltip.graphicscard=Used to change what's displayed on screens.[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7 -oc:tooltip.hoverboots=Jump higher, fall deeper, walk better. This and more, with the new and patented Hover Boots (TM). -oc:tooltip.inkcartridge=Used to refill ink in 3D printers. For mysterious reasons it does not have to remain in the printer. -oc:tooltip.inkcartridgeempty=This ink cartridge has been sucked dry. Refill it using dyes. Or throw it away. See if I care. -oc:tooltip.internetcard=This card allows making HTTP requests and using real TCP sockets. -oc:tooltip.interweb=Congratulations, you win one (1) interweb. You can connect to it using an Internet Card. Beware: don't feed the trolls. -oc:tooltip.ironnugget=A nugget made of iron, that's why it's called an Iron Nugget, duh... -oc:tooltip.keyboard=Can be attached to screens to allow typing on them. -oc:tooltip.hologram0=A volumetric display that can be controlled by computers to display arbitrary voxel structures.[nl] Resolution: §f48x32x48§7 [nl] Maximum scale: §f3x§7 [nl] Color depth: §fMonochrome§7 -oc:tooltip.hologram1=A volumetric display that can be controlled by computers to display arbitrary voxel structures.[nl] Resolution: §f48x32x48§7 [nl] Maximum scale: §f4x§7 [nl] Color depth: §fTricolor§7 -oc:tooltip.linkedcard=These are crafted in pairs, and can only communicate with their partner card. However, they can communicate across any distance, and even across dimensions. The energy required to send a message is fairly high, though. -oc:tooltip.linkedcard_channel=§8Channel: %s§7 -oc:tooltip.manual=All the information you could possibly need about OpenComputers. And more. For the unbelievably low price of... §oplease press R to continue§7. -oc:tooltip.memory=Required to get computers to run. The more you have, the more complex the programs you can run. -oc:tooltip.microchip=The chip formerly known as Integrated Circuit. I have no idea why this works with redstone, but it does. -oc:tooltip.microcontroller=Microcontrollers are computers boiled down to the essentials. They are intended to take care of very specific tasks, running only a single program that is provided on the EEPROM built into them.[nl] §cCan not connect to external components.§7 -oc:tooltip.microcontrollercase=Base component for building microcontrollers. Place it into an assembler to add further components and assemble a microcontroller. -oc:tooltip.motionsensor=Can detect movement of nearby living beings. Requires clear line-of-sight. -oc:tooltip.nanomachines=Control unit and a bunch of nanomachines for ingestion, if you dare. -oc:tooltip.networkcard=Allows distant computers connected by other blocks (such as cable) to communicate by sending messages to each other. -oc:tooltip.poweracceptor=Energy conversion speed: §f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§fBuildCraft MJ§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§fFactorization Charge§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fIndustrialCraft² EU§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§fMekanism Joules§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fThermal Expansion RF§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fResonant Engine Coulombs§7: §a%s:%s§7 -oc:tooltip.powerconverter=Converts power from other mods to the internal energy type. Conversion rates: -oc:tooltip.powerdistributor=Distributes energy among different networks. This is useful for sharing power fed into your system from one converter among different sub-networks that should remain separate. -oc:tooltip.present=... for your troubles. Open this present for a chance to receive some §kphat lewt§7![nl]§8Craft OpenComputers items when the time is right for a chance to receive a present.§7 -oc:tooltip.print.BeaconBase=§8Works as a beacon base. -oc:tooltip.print.LightValue=§8Light emitted: %s. -oc:tooltip.print.RedstoneLevel=§8Redstone output: %s. -oc:tooltip.printedcircuitboard=The basic building block for expansion cards and memory and such. -oc:tooltip.printer=Allows printing blocks of user-defined shapes using Chamelium and Ink Cartridges. Must be configured using a computer. Keep away from small children. Because reasons. -oc:tooltip.raid=Allows combining three hard drives into one larger file system that can be used by all connected computers. -oc:tooltip.rawcircuitboard=Can be hardened in any furnace compatible oven. -oc:tooltip.redstone=Allows reading and emitting redstone signals around the block. Can be controlled by any computer the block is connected to. This is basically like an external redstone card. -oc:tooltip.redstonecard.Charset=§fSimpleLogic§7 is §asupported§7. -oc:tooltip.redstonecard.ProjectRed=§fProjectRed§7 is §asupported§7. -oc:tooltip.redstonecard.RedLogic=§fRedLogic§7 is §asupported§7. -oc:tooltip.redstonecard.RedNet=§fRedNet§7 is §asupported§7. -oc:tooltip.redstonecard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 is §asupported§7. -oc:tooltip.redstonecard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 is §asupported§7. -oc:tooltip.redstonecard=Allows reading and emitting redstone signals around the computer or robot. -oc:tooltip.relay=Allows connecting different networks to each other. Only network messages will be passed along, components will not be visible through this. Use this to separate networks while still allowing communication using Network Cards, for example. -oc:tooltip.robot=Unlike computers, robots can move around and interact with the world much like a player can.[nl] §cCan not connect to external components.§7 -# the underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fLevel§7: §a%s§7 -oc:tooltip.robot_storedenergy=§fStored energy§7: §a%s§7 -oc:tooltip.screen=Display text, controlled by a Graphics Card in a Case.[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7 -oc:tooltip.server=This is a server, there are many like it, but this one can be upgraded with components much like a computer case can be. It can be run by inserting it into a server rack. -oc:tooltip.server.Components=Installed components: -oc:tooltip.rack=Allows the installation of up to four servers or other rack mountables. -oc:tooltip.tablet=A tablet computer, for fresh Lua on the go. Can be forced to shut down by sneak-activating it. -oc:tooltip.tabletcase=Basic case for tablets. Place it into the assembler to add in components and create a tablet computer. -oc:tooltip.terminal=Allows controlling a server remotely, as long as you are in range of it. Acts like a portable screen and keyboard. Shift-right-click a server in a server rack to bind the terminal to it. -oc:tooltip.terminalserver=Backend to which Remote Terminals can be connected to provide remote control. Houses a virtual screen and keyboard. -oc:tooltip.texturepicker=This tool allows showing a string describing a block's surface, for use in 3D printer shape definitions. Totally not texture names, nope. No sir. -oc:tooltip.tier=§8Tier %s -oc:tooltip.netsplitter=Acts as a dynamic connector. Connectivity of each side can be toggled by hitting it with a wrench. Connectivity of all sides can be inverted by applying a redstone signal. -oc:tooltip.toolong=Hold [§f%s§7] for a detailed tooltip. -oc:tooltip.transistor=A basic element in most other computer parts. It's a bit twisted, but it does the job. -oc:tooltip.transposer=Allows automated transferral of items and fluids between adjacent inventories and fluid containers. -oc:tooltip.upgradeangel=Allows robots to place blocks in thin air, even if there is no point of reference. -oc:tooltip.upgradebattery=Increase the amount of energy a device can store, allowing it work longer without having to be recharged. [nl] Capacity: §f%s§7 -oc:tooltip.upgradechunkloader=If a robot moves in a forest and no one is around to see it, does it really move? This upgrades makes sure it does. It keeps the chunk a device is in loaded, but continually consumes energy while active. -oc:tooltip.upgradecontainercard=This container upgrade allows dynamically installing and removing a card from an assembled device. [nl] Maximum Tier: §f%s§7 -oc:tooltip.upgradecontainerupgrade=This container upgrade allows dynamically installing and removing another upgrade from an assembled device. [nl] Maximum Tier: §f%s§7 -oc:tooltip.upgradecrafting=Enables robots to use the top left area of their inventory for crafting objects. Items have to be aligned as they would be in a crafting table. -oc:tooltip.upgradedatabase=This upgrade allows storing item stack information for later retrieval and use by other components.[nl] Supported entries: §f%s§7 -oc:tooltip.upgradeexperience=This upgrade allows robots to accumulate experience by performing various operations. The more experience they have, the more energy they can store, the faster they can harvest blocks and the more efficiently they can use tools. -oc:tooltip.upgradegenerator=Can be used to generate energy from fuel on the go. Burns items to generate energy over time, based on their fuel value.[nl] §fEfficiency§7: §a%s%%§7 -oc:tooltip.upgradehover=This upgrade allows robots to fly higher above the ground without having to climb walls.[nl] Maximum height: §f%s§7 -oc:tooltip.upgradeinventory=This upgrade provides inventory space to a robot or drone. Without one of these, they will not be able to store items internally. -oc:tooltip.upgradeinventorycontroller=This upgrade allows robots and drones more control in how it interact with external inventories, and allows robots to swap their equipped tool with an item in their inventory. -oc:tooltip.upgrademf=Allows adapters to access blocks they are not adjacent to. -oc:tooltip.upgrademf.Linked=§fConnection established§7 -oc:tooltip.upgrademf.Unlinked=§fNo connection§7 -oc:tooltip.upgradeleash=Allows some devices, such as drones, to bind Isaa- excuse me... *chatter* My apologies. I'm just being told this is actually used to put animals on a leash. Multiple animals, even. Odd. -oc:tooltip.upgradenavigation=Can be used to determine the position and orientation of a device. The position is relative to the center of the map that was used to craft this upgrade. -oc:tooltip.upgradepiston=This upgrade is very pushy. It allows moving blocks, similar to a piston. -oc:tooltip.upgradestickypiston=This upgrade can push and pull. It allows moving blocks, similar to a sticky piston. It does §lnot§7 pull entities, however. -oc:tooltip.upgradesign=Allows reading text on and writing text to signs. -oc:tooltip.upgradesolargenerator=Can be used to generate energy from sunlight on the go. Requires a clear line of sight to the sky above the device. Generates energy at %s%% of the speed of a Stirling Engine. -oc:tooltip.upgradetank=This upgrade provides a tank for fluid storage for robots and drones. Without one of these, they will not be able to store fluids internally. -oc:tooltip.upgradetankcontroller=This upgrade allows robots and drones more control in how they interact with external tanks, and allows them to transfer fluids into and out of fluid tank items in their inventory. -oc:tooltip.upgradetractorbeam=Equips a device with extremely advanced technology, nicknamed the "Item Magnet". Allows the device to pick up items anywhere within 3 blocks of its location. -oc:tooltip.upgradetrading=Allows robots and drones to trade with villagers. -oc:tooltip.waypoint=Provides a point of reference to devices with a navigation upgrade. -oc:tooltip.wirelessnetworkcard=Allows wireless sending of network messages in addition to normal ones. You can adjust the §fsignal strength§7 to control how far messages are sent. Higher signal strength results in higher energy consumption. -oc:tooltip.worldsensorcard=Allows reading out information about the world, such as its gravity and whether it has a breathable atmosphere. Use results at own risk. The manufacturer takes no responsibility for bodily or material harm caused by decisions made upon the cards' outputs. We have lawyers. And money. Don't even try. -oc:tooltip.Wrench=A hybrid of Screwdriver and Wrench, this tool is easy to learn, but hard to master. - -#Achievements -achievement.oc.adapter=Plug In Baby -achievement.oc.adapter.desc=Interact with blocks from other mods and even vanilla Minecraft! -achievement.oc.assembler=Wonderful -achievement.oc.assembler.desc=Time to take over the world! -achievement.oc.cable=Not a Dirty Wire -achievement.oc.cable.desc=With patented anti-cable-spaghetti technology. -achievement.oc.capacitor=Batteries included -achievement.oc.capacitor.desc=You cannot stop it. -achievement.oc.card=We Accept Cards -achievement.oc.card.desc=For your convenience. No ulterior motive, promise. -achievement.oc.case=In Case of Trouble -achievement.oc.case.desc=Because cuboid towers are the best. -achievement.oc.charger=All right, let's do this -achievement.oc.charger.desc=Chaaaaaaaaaarg- dang, forgot the redstone signal again. -achievement.oc.chip=All the Small Things -achievement.oc.chip.desc=Because vacuum tubes are so yesteryear. -achievement.oc.cpu=Overclocked -achievement.oc.cpu.desc=Time to make good use of those computing cycles. -achievement.oc.disassembler=Scratch That -achievement.oc.disassembler.desc=In case one of your brilliant ideas turns out to be not that brilliant after all. -achievement.oc.diskDrive=Roundabout -achievement.oc.diskDrive.desc=Inferior capacity but such delicious sound. -achievement.oc.drone=Fly Away -achievement.oc.drone.desc=Keep calm and nuke it from orbit. -achievement.oc.eeprom=There can be only one -achievement.oc.eeprom.desc=Per computer, that is. For deterministic boot order, you know? -achievement.oc.floppy=The One Ri- Disk -achievement.oc.floppy.desc=Not to be confused with Flappy. -achievement.oc.geolyzer=Down to Earth -achievement.oc.geolyzer.desc=It has extraordinary qualities. -achievement.oc.graphicsCard=LastGen -achievement.oc.graphicsCard.desc=The way it's meant to be... uh... rendered. Yeah. That. -achievement.oc.hdd=Hot Dog Dealer -achievement.oc.hdd.desc=No wait, that's not what that meant. Hang on, almost got it... -achievement.oc.hologram=Next Dimension -achievement.oc.hologram.desc=Because 2D is boring. Or is it? -achievement.oc.keyboard=DirtCatcher3000 -achievement.oc.keyboard.desc=It is highly recommended to resist the urge to flip them around and shake them. -achievement.oc.microcontroller=Little Sister -achievement.oc.microcontroller.desc=The small sibling of computers. -achievement.oc.motionSensor=Got the Moves -achievement.oc.motionSensor.desc=Like Steve Swagger. -achievement.oc.networkCard=Now We're Talking! -achievement.oc.networkCard.desc=Keep in touch with those distant relatives via transitive relations. -achievement.oc.openOS=Boot -achievement.oc.openOS.desc=One OS to - wait, I used that one already? Dang. -achievement.oc.powerDistributor=Sharing is Caring -achievement.oc.powerDistributor.desc=When you need some help balancing all that power. -achievement.oc.rack=Dat Rack -achievement.oc.rack.desc=I don't know what you're thinking of, I clearly meant the server rack. -achievement.oc.raid=LFG -achievement.oc.raid.desc=Heroic plzkthx. -achievement.oc.ram=Random Access Memories -achievement.oc.ram.desc=Congratulations, you're Doin' It Right. -achievement.oc.redstoneCard=Contact -achievement.oc.redstoneCard.desc=Time to go analog. -achievement.oc.redstoneIO=The Outsider -achievement.oc.redstoneIO.desc=Taking redstone signals where you want them. -achievement.oc.robot=Beep Boop -achievement.oc.robot.desc=EXTERMINATE! -achievement.oc.screen=Have you tried turning it off and on again? -achievement.oc.screen.desc=No seriously. A redstone pulse can toggle a screen's power, after all. -achievement.oc.server=Dedicated -achievement.oc.server.desc=Cloud services, here we come. -achievement.oc.switch=Complex Topology -achievement.oc.switch.desc=Avoid fragile goods due to possibility of dropped packets. -achievement.oc.tablet=Do Not Swallow -achievement.oc.tablet.desc=Also keep away from small children to avoid unexpected overdrawing of your credit card. -achievement.oc.transistor=Tell Red I said "Hi." -achievement.oc.transistor.desc=Create a Transistor to get started. Then listen to the soundtrack. No need to thank me. -achievement.oc.wirelessNetworkCard=Signals -achievement.oc.wirelessNetworkCard.desc=Time to go where no packet has gone before. - -# Death messages. Note that the number of entries here must match the number -# set in the actual damage source in code. -death.attack.oc.nanomachinesOverload.1=%s got too greedy. -death.attack.oc.nanomachinesOverload.2=%s had a nervous breakdown. -death.attack.oc.nanomachinesOverload.3=The nanomachines of %s went out of control. -death.attack.oc.nanomachinesHungry.1=%s was eaten by nanomachines. -death.attack.oc.nanomachinesHungry.2=%s didn't keep their nanomachines fed. -death.attack.oc.nanomachinesHungry.3=%s has been digested. - -# NEI Integration -nei.options.inventory.oredict=Show OreDictionary names -nei.options.inventory.oredict.true=True -nei.options.inventory.oredict.false=False -nei.usage.oc.Manual=Open Manual - -# Waila Integration -option.oc.address=Address -option.oc.componentName=Component Name -option.oc.energy=Energy diff --git a/src/main/resources/assets/opencomputers/lang/en_us.json b/src/main/resources/assets/opencomputers/lang/en_us.json new file mode 100644 index 0000000000..5d4d881651 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/en_us.json @@ -0,0 +1,461 @@ +{ + "tile.oc.adapter": "Adapter", + "tile.oc.assembler": "Electronics Assembler", + "tile.oc.cable": "Cable", + "tile.oc.capacitor": "Capacitor", + "tile.oc.carpetedcapacitor": "Carpeted Capacitor", + "tile.oc.case1": "Computer Case (Tier 1)", + "tile.oc.case2": "Computer Case (Tier 2)", + "tile.oc.case3": "Computer Case (Tier 3)", + "tile.oc.casecreative": "Computer Case (Creative)", + "tile.oc.chameliumblock": "Block of Chamelium", + "tile.oc.charger": "Charger", + "tile.oc.disassembler": "Disassembler", + "tile.oc.diskdrive": "Disk Drive", + "tile.oc.endstone": "End Stone", + "tile.oc.geolyzer": "Geolyzer", + "tile.oc.hologram1": "Hologram Projector (Tier 1)", + "tile.oc.hologram2": "Hologram Projector (Tier 2)", + "tile.oc.keyboard": "Keyboard", + "tile.oc.microcontroller": "Microcontroller", + "tile.oc.motionsensor": "Motion Sensor", + "tile.oc.netsplitter": "Net Splitter", + "tile.oc.powerconverter": "Power Converter", + "tile.oc.powerdistributor": "Power Distributor", + "tile.oc.print": "3D Print", + "tile.oc.printer": "3D Printer", + "tile.oc.raid": "Raid", + "tile.oc.redstone": "Redstone I/O", + "tile.oc.relay": "Relay", + "tile.oc.robot": "Robot", + "tile.oc.robotafterimage": "Robot", + "tile.oc.screen1": "Screen (Tier 1)", + "tile.oc.screen2": "Screen (Tier 2)", + "tile.oc.screen3": "Screen (Tier 3)", + "tile.oc.rack": "Rack", + "tile.oc.transposer": "Transposer", + "tile.oc.waypoint": "Waypoint", + "item.oc.abstractbuscard": "Abstract Bus Card", + "item.oc.acid": "Grog", + "item.oc.alu": "Arithmetic Logic Unit (ALU)", + "item.oc.analyzer": "Analyzer", + "item.oc.apu0": "Accelerated Processing Unit (APU) (Tier 2)", + "item.oc.apu1": "Accelerated Processing Unit (APU) (Tier 3)", + "item.oc.apu2": "Accelerated Processing Unit (APU) (Creative)", + "item.oc.arrowkeys": "Arrow Keys", + "item.oc.buttongroup": "Button Group", + "item.oc.cardbase": "Card Base", + "item.oc.chamelium": "Chamelium", + "item.oc.circuitboard": "Circuit Board", + "item.oc.componentbus0": "Component Bus (Tier 1)", + "item.oc.componentbus1": "Component Bus (Tier 2)", + "item.oc.componentbus2": "Component Bus (Tier 3)", + "item.oc.componentbus3": "Component Bus (Creative)", + "item.oc.controlunit": "Control Unit (CU)", + "item.oc.cpu0": "Central Processing Unit (CPU) (Tier 1)", + "item.oc.cpu1": "Central Processing Unit (CPU) (Tier 2)", + "item.oc.cpu2": "Central Processing Unit (CPU) (Tier 3)", + "item.oc.cuttingwire": "Cutting Wire", + "item.oc.datacard0": "Data Card (Tier 1)", + "item.oc.datacard1": "Data Card (Tier 2)", + "item.oc.datacard2": "Data Card (Tier 3)", + "item.oc.debugcard": "Debug Card", + "item.oc.debugger": "Network Debugger", + "item.oc.diamondchip": "Diamond Chip", + "item.oc.disk": "Disk Platter", + "item.oc.diskdrivemountable": "Disk Drive", + "item.oc.drone": "Drone", + "item.oc.dronecase0": "Drone Case (Tier 1)", + "item.oc.dronecase1": "Drone Case (Tier 2)", + "item.oc.dronecase3": "Drone Case (Creative)", + "item.oc.eeprom": "EEPROM", + "item.oc.floppydisk": "Floppy Disk", + "item.oc.graphicscard0": "Graphics Card (Tier 1)", + "item.oc.graphicscard1": "Graphics Card (Tier 2)", + "item.oc.graphicscard2": "Graphics Card (Tier 3)", + "item.oc.harddiskdrive0": "Hard Disk Drive (Tier 1)", + "item.oc.harddiskdrive1": "Hard Disk Drive (Tier 2)", + "item.oc.harddiskdrive2": "Hard Disk Drive (Tier 3)", + "item.oc.hoverboots": "Hover Boots", + "item.oc.inkcartridge": "Ink Cartridge", + "item.oc.inkcartridgeempty": "Ink Cartridge (Empty)", + "item.oc.internetcard": "Internet Card", + "item.oc.interweb": "Interweb", + "item.oc.ironnugget": "Iron Nugget", + "item.oc.linkedcard": "Linked Card", + "item.oc.manual": "OpenComputers Manual", + "item.oc.memory0": "Memory (Tier 1)", + "item.oc.memory1": "Memory (Tier 1.5)", + "item.oc.memory2": "Memory (Tier 2)", + "item.oc.memory3": "Memory (Tier 2.5)", + "item.oc.memory4": "Memory (Tier 3)", + "item.oc.memory5": "Memory (Tier 3.5)", + "item.oc.microchip0": "Microchip (Tier 1)", + "item.oc.microchip1": "Microchip (Tier 2)", + "item.oc.microchip2": "Microchip (Tier 3)", + "item.oc.microcontrollercase0": "Microcontroller Case (Tier 1)", + "item.oc.microcontrollercase1": "Microcontroller Case (Tier 2)", + "item.oc.microcontrollercase3": "Microcontroller Case (Creative)", + "item.oc.nanomachines": "Nanomachines", + "item.oc.networkcard": "Network Card", + "item.oc.numpad": "Numeric Keypad", + "item.oc.present": "A little something...", + "item.oc.printedcircuitboard": "Printed Circuit Board (PCB)", + "item.oc.rawcircuitboard": "Raw Circuit Board", + "item.oc.redstonecard0": "Redstone Card (Tier 1)", + "item.oc.redstonecard1": "Redstone Card (Tier 2)", + "item.oc.server0": "Server (Tier 1)", + "item.oc.server1": "Server (Tier 2)", + "item.oc.server2": "Server (Tier 3)", + "item.oc.server3": "Server (Creative)", + "item.oc.tablet": "Tablet", + "item.oc.tabletcase0": "Tablet Case (Tier 1)", + "item.oc.tabletcase1": "Tablet Case (Tier 2)", + "item.oc.tabletcase3": "Tablet Case (Creative)", + "item.oc.terminal": "Remote Terminal", + "item.oc.terminalserver": "Terminal Server", + "item.oc.texturepicker": "Texture Picker", + "item.oc.transistor": "Transistor", + "item.oc.upgradeangel": "Angel Upgrade", + "item.oc.upgradebattery0": "Battery Upgrade (Tier 1)", + "item.oc.upgradebattery1": "Battery Upgrade (Tier 2)", + "item.oc.upgradebattery2": "Battery Upgrade (Tier 3)", + "item.oc.upgradechunkloader": "Chunkloader Upgrade", + "item.oc.upgradecontainercard0": "Card Container (Tier 1)", + "item.oc.upgradecontainercard1": "Card Container (Tier 2)", + "item.oc.upgradecontainercard2": "Card Container (Tier 3)", + "item.oc.upgradecontainerupgrade0": "Upgrade Container (Tier 1)", + "item.oc.upgradecontainerupgrade1": "Upgrade Container (Tier 2)", + "item.oc.upgradecontainerupgrade2": "Upgrade Container (Tier 3)", + "item.oc.upgradecrafting": "Crafting Upgrade", + "item.oc.upgradedatabase0": "Database Upgrade (Tier 1)", + "item.oc.upgradedatabase1": "Database Upgrade (Tier 2)", + "item.oc.upgradedatabase2": "Database Upgrade (Tier 3)", + "item.oc.upgradeexperience": "Experience Upgrade", + "item.oc.upgradegenerator": "Generator Upgrade", + "item.oc.upgradehover0": "Hover Upgrade (Tier 1)", + "item.oc.upgradehover1": "Hover Upgrade (Tier 2)", + "item.oc.upgradeinventory": "Inventory Upgrade", + "item.oc.upgradeinventorycontroller": "Inventory Controller Upgrade", + "item.oc.upgradeleash": "Leash Upgrade", + "item.oc.upgrademf": "MFU", + "item.oc.upgradenavigation": "Navigation Upgrade", + "item.oc.upgradepiston": "Piston Upgrade", + "item.oc.upgradestickypiston": "Sticky Piston Upgrade", + "item.oc.upgradesign": "Sign I/O Upgrade", + "item.oc.upgradesolargenerator": "Solar Generator Upgrade", + "item.oc.upgradetank": "Tank Upgrade", + "item.oc.upgradetankcontroller": "Tank Controller Upgrade", + "item.oc.upgradetractorbeam": "Tractor Beam Upgrade", + "item.oc.upgradetrading": "Trading Upgrade", + "item.oc.wirelessnetworkcard0": "Wireless Network Card (Tier 1)", + "item.oc.wirelessnetworkcard1": "Wireless Network Card (Tier 2)", + "item.oc.worldsensorcard": "World Sensor Card", + "item.oc.wrench": "Scrench", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.Drone": "Drone", + "oc:gui.Analyzer.Address": "§6Address§f: %s", + "oc:gui.Analyzer.AddressCopied": "Address copied to clipboard.", + "oc:gui.Analyzer.ChargerSpeed": "§6Charge speed§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Component name§f: %s", + "oc:gui.Analyzer.Components": "§6Number of connected components§f: %s", + "oc:gui.Analyzer.CopyToClipboard": "Click to copy to clipboard.", + "oc:gui.Analyzer.LastError": "§6Last error§f: %s", + "oc:gui.Analyzer.RobotName": "§6Name§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Owner§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Experience§f: %s (Level %s)", + "oc:gui.Analyzer.StoredEnergy": "§6Stored energy§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Total stored energy§f: %s", + "oc:gui.Analyzer.Users": "§6Users§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6Signal strength§f: %s", + "oc:gui.Assembler.Collect": "Collect output", + "oc:gui.Assembler.Complexity": "Complexity: %s/%s", + "oc:gui.Assembler.InsertCase": "Insert a base part", + "oc:gui.Assembler.InsertCPU": "Insert a CPU", + "oc:gui.Assembler.InsertRAM": "Insert some RAM", + "oc:gui.Assembler.Progress": "Progress: %s%% (%s)", + "oc:gui.Assembler.Run": "Assemble", + "oc:gui.Assembler.Warning.BIOS": "BIOS", + "oc:gui.Assembler.Warning.GraphicsCard": "Graphics Card", + "oc:gui.Assembler.Warning.Inventory": "Inventory Upgrade", + "oc:gui.Assembler.Warning.Keyboard": "Keyboard", + "oc:gui.Assembler.Warning.OS": "Bootable Medium", + "oc:gui.Assembler.Warning.Screen": "Screen", + "oc:gui.Assembler.Warnings": "§eWarning§7: Recommended components are missing.", + "oc:gui.Chat.NewVersion": "A new version is available: %s", + "oc:gui.Chat.TextureName": "§7Texture name is §a%s§f.", + "oc:gui.Chat.WarningClassTransformer": "There were §cerrors§f running the class transformer. Please report this, together with your (full!) FML §alatest.log§f/§afml-server-latest.log§f logfile, thank you!", + "oc:gui.Chat.WarningFingerprint": "§cWARNING§f - fingerprint mismatch! Expected '§a%s§f' but got '§e%s§f'. Unless you are a modder and are running the deobfuscated version of the mod, it is §lstrongly§f recommended to redownload OpenComputers, because the JAR you are using may have been tampered with.", + "oc:gui.Chat.WarningLink": "Could not open link: %s", + "oc:gui.Chat.WarningLuaFallback": "Native Lua libraries are not available, computers will not be able to persist their state. They will reboot on chunk reloads.", + "oc:gui.Chat.WarningProjectRed": "You are using a version of Project: Red that is incompatible with OpenComputers. Try updating your version of Project: Red.", + "oc:gui.Chat.WarningRecipes": "There were errors loading one or more recipes. Some items may be uncraftable. Please check your log file for more information.", + "oc:gui.Drive.Managed": "Managed", + "oc:gui.Drive.Unmanaged": "Unmanaged", + "oc:gui.Drive.ReadOnlyLock": "Lock", + "oc:gui.Drive.ReadOnlyLockWarning": "§lRead Only§r lock. Cannot be removed unless the drive is wiped.", + "oc:gui.Drive.Warning": "§lWarning§r: switching modes will result in a loss of all data currently stored on the disk!", + "oc:gui.Error.ComponentOverflow": "Too many components connected to the computer.", + "oc:gui.Error.InternalError": "Internal error, please see the log file. This is probably a bug.", + "oc:gui.Error.NoCPU": "No CPU is installed in the computer.", + "oc:gui.Error.NoEnergy": "Not enough energy.", + "oc:gui.Error.NoRAM": "No RAM is installed in the computer.", + "oc:gui.Error.OutOfMemory": "Out of memory.", + "oc:gui.Manual.Blocks": "OpenComputers Blocks", + "oc:gui.Manual.Home": "Home", + "oc:gui.Manual.Items": "OpenComputers Items", + "oc:gui.Manual.Warning.BlockMissing": "Block unavailable.", + "oc:gui.Manual.Warning.ImageMissing": "Image not found.", + "oc:gui.Manual.Warning.ItemMissing": "Item unavailable.", + "oc:gui.Manual.Warning.OreDictMissing": "Ore dictionary entry unavailable.", + "oc:gui.Raid.Warning": "§4Adding a disk wipes it.\nRemoving a disk wipes the raid.", + "oc:gui.Robot.Power": "Energy", + "oc:gui.Robot.TurnOff": "Turn off", + "oc:gui.Robot.TurnOn": "Turn on\n§7Use an Analyzer to troubleshoot errors.§r", + "oc:gui.Rack.Back": "Back", + "oc:gui.Rack.Bottom": "Bottom", + "oc:gui.Rack.Left": "Left", + "oc:gui.Rack.None": "None", + "oc:gui.Rack.Right": "Right", + "oc:gui.Rack.Enabled": "Enabled", + "oc:gui.Rack.Disabled": "Disabled", + "oc:gui.Rack.RelayModeTooltip": "Relay Mode", + "oc:gui.Rack.Top": "Top", + "oc:gui.Switch.PacketsPerCycle": "Packets / cycle", + "oc:gui.Switch.QueueSize": "Queue size", + "oc:gui.Switch.TransferRate": "Cycle rate", + "oc:gui.Terminal.InvalidKey": "Invalid key, most likely another terminal has been bound to the server.", + "oc:gui.Terminal.OutOfRange": "No signal.", + "oc:container.adapter": "Adapter", + "oc:container.case": "Computer", + "oc:container.charger": "Charger", + "oc:container.disassembler": "Disassembler", + "oc:container.diskdrive": "Disk Drive", + "oc:container.printer": "Printer", + "oc:container.raid": "Raid", + "oc:container.relay": "Relay", + "oc:container.server": "Server", + "oc:container.rack": "Rack", + "oc:container.tabletwrapper": "Tablet", + "key.opencomputers.analyzeCopyAddress": "Copy Address (Analyzer)", + "key.opencomputers.clipboardPaste": "Paste Clipboard", + "key.opencomputers.extendedTooltip": "Show Detailed Tooltips", + "oc:tooltip.abstractbuscard": "Allows interacting with §fStargateTech 2§7's abstract bus by sending and receiving LIP packets.", + "oc:tooltip.acid": "A highly toxic pseudo-liquid, usually only consumed by certain pirates. May prove to be useful in other ways, too, however.", + "oc:tooltip.adapter": "Used to control non-component blocks, such as vanilla blocks or blocks from other mods.", + "oc:tooltip.alu": "Adds numbers so you don't have to. It might be better this way.", + "oc:tooltip.analyzer": "Used to display information about blocks, such as their §faddress§7 and §fcomponent name§7.\nAlso displays the error that caused a computer to crash if it did not shut down normally.", + "oc:tooltip.apu": "This is a CPU with an integrated GPU (or IGP), when you just need that extra card slot.\nSupported components: §f%s§7\nMaximum resolution: §f%sx%s§7\nMaximum color depth: §f%s§7\nOperations/tick: §f%s§7", + "oc:tooltip.assembler": "Allows constructing robots and other devices from a number of different computer parts.", + "oc:tooltip.cable": "A cheap way of connecting blocks.", + "oc:tooltip.capacitor": "Stores energy for later use. Can be filled and emptied very quickly.", + "oc:tooltip.carpetedcapacitor": "Stores energy for later use. Can be filled and emptied very quickly. Charges when Sheep or Ocelots walk on it", + "oc:tooltip.cardbase": "As the name indicates, this is the basic building block for all expansion cards.", + "oc:tooltip.case": "The Computer Case is the basic building block for computers and houses the computer's §fextension cards§7, §fRAM§7 and §fhard disks§7.\nSlots: §f%s§7", + "oc:tooltip.chamelium": "Raw material for 3D prints. Do not swallow: may lead to blindness and temporary lack of presence.", + "oc:tooltip.chameliumblock": "Nice and clean. Handy for tinted shapes in 3D prints, or just for having a clean, colored block to decorate your fancy base with.", + "oc:tooltip.charger": "Transfers energy from capacitors into adjacent robots and drones. The transfer rate depends on the incoming §fredstone signal§7, where no signal means don't charge devices, and maximum strength means charge at full speed. Can also be used to charge tablets and access hard drives in tablets.", + "oc:tooltip.circuitboard": "Now we're getting somewhere. Can be etched to obtain a printed circuit board.", + "oc:tooltip.controlunit": "This is the unit that... controls... stuff. You need it to build a CPU. So yeah, totally important.", + "oc:tooltip.componentbus": "This expansion allows servers to communicate with more components at the same time, similar to how CPUs do.\nSupported components: §f%s§7", + "oc:tooltip.cpu": "An essential component of all computers. The clock rate is a bit unreliable, but what do you expect when it runs on a pocket sundial?\nSupported components: §f%s§7", + "oc:tooltip.cpu.Architecture": "Architecture: §f%s§7", + "oc:tooltip.cuttingwire": "Used to cut clay blocks into circuit board shape. Breaks after one use, which probably makes it the most inefficient tool ever.", + "oc:tooltip.datacard0": "Provides a couple of advanced algorithms such as hashing and deflate/inflate.", + "oc:tooltip.datacard1": "Provides a couple of advanced algorithms such as hashing, AES encryption and deflate/inflate.", + "oc:tooltip.datacard2": "Provides a couple of advanced algorithms such as hashing, AES encryption, elliptic curve cryptography and deflate/inflate.", + "oc:tooltip.debugcard": "Creative mode item, allows manipulating the world to make testing easier. Use at your own peril.", + "oc:tooltip.debugger": "Can be used to output debug information on OC's internal network grid. Only use if so instructed by a dev.", + "oc:tooltip.diamondchip": "A small piece of a once radiant diamond. It will never be the same again.", + "oc:tooltip.disassembler": "Separates items into their original components. §lWarning§7: returned items have a %s%% chance of breaking in the process!", + "oc:tooltip.disk": "Primitive medium that can be used to build persistent storage devices.", + "oc:tooltip.diskdrive.CC": "ComputerCraft floppies are §asupported§7.", + "oc:tooltip.diskdrive": "Allows reading and writing floppies. Can be installed in robots to allow inserting floppies later on.", + "oc:tooltip.diskdrivemountable": "Provides the same functionality as a normal disk drive, but must be installed in a rack.", + "oc:tooltip.diskusage": "Disk usage: %s/%s Byte", + "oc:tooltip.disklocked": "Locked by: %s", + "oc:tooltip.diskmodemanaged": "Mode: Managed", + "oc:tooltip.diskmodeunmanaged": "Mode: Unmanaged", + "oc:tooltip.drone": "Drones are light-weight, fast reconnaissance units with limited cargo space.", + "oc:tooltip.dronecase": "This casing is used to build Drones in the assembler. It has room for a small amount of components and provides endstone-powered levitation.", + "oc:tooltip.eeprom": "Small, programmable storage that contains the BIOS computers use to boot.", + "oc:tooltip.fakeendstone": "Almost as good as the real thing, even emulates its floatiness!", + "oc:tooltip.geolyzer": "Allows scanning the surrounding area's blocks' hardness. This information can be useful for generating holograms of the area or for detecting ores.", + "oc:tooltip.graphicscard": "Used to change what's displayed on screens.\nMaximum resolution: §f%sx%s§7\nMaximum color depth: §f%s§7\nOperations/tick: §f%s§7", + "oc:tooltip.hoverboots": "Jump higher, fall deeper, walk better. This and more, with the new and patented Hover Boots (TM).", + "oc:tooltip.inkcartridge": "Used to refill ink in 3D printers. For mysterious reasons it does not have to remain in the printer.", + "oc:tooltip.inkcartridgeempty": "This ink cartridge has been sucked dry. Refill it using dyes. Or throw it away. See if I care.", + "oc:tooltip.internetcard": "This card allows making HTTP requests and using real TCP sockets.", + "oc:tooltip.interweb": "Congratulations, you win one (1) interweb. You can connect to it using an Internet Card. Beware: don't feed the trolls.", + "oc:tooltip.ironnugget": "A nugget made of iron, that's why it's called an Iron Nugget, duh...", + "oc:tooltip.keyboard": "Can be attached to screens to allow typing on them.", + "oc:tooltip.hologram0": "A volumetric display that can be controlled by computers to display arbitrary voxel structures.\nResolution: §f48x32x48§7\nMaximum scale: §f3x§7\nColor depth: §fMonochrome§7", + "oc:tooltip.hologram1": "A volumetric display that can be controlled by computers to display arbitrary voxel structures.\nResolution: §f48x32x48§7\nMaximum scale: §f4x§7\nColor depth: §fTricolor§7", + "oc:tooltip.linkedcard": "These are crafted in pairs, and can only communicate with their partner card. However, they can communicate across any distance, and even across dimensions. The energy required to send a message is fairly high, though.", + "oc:tooltip.linkedcard_channel": "§8Channel: %s§7", + "oc:tooltip.manual": "All the information you could possibly need about OpenComputers. And more. For the unbelievably low price of... §oplease press R to continue§7.", + "oc:tooltip.memory": "Required to get computers to run. The more you have, the more complex the programs you can run.", + "oc:tooltip.microchip": "The chip formerly known as Integrated Circuit. I have no idea why this works with redstone, but it does.", + "oc:tooltip.microcontroller": "Microcontrollers are computers boiled down to the essentials. They are intended to take care of very specific tasks, running only a single program that is provided on the EEPROM built into them.\n§cCan not connect to external components.§7", + "oc:tooltip.microcontrollercase": "Base component for building microcontrollers. Place it into an assembler to add further components and assemble a microcontroller.", + "oc:tooltip.motionsensor": "Can detect movement of nearby living beings. Requires clear line-of-sight.", + "oc:tooltip.nanomachines": "Control unit and a bunch of nanomachines for ingestion, if you dare.", + "oc:tooltip.networkcard": "Allows distant computers connected by other blocks (such as cable) to communicate by sending messages to each other.", + "oc:tooltip.poweracceptor": "Energy conversion speed: §f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§fBuildCraft MJ§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§fFactorization Charge§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fIndustrialCraft² EU§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§fMekanism Joules§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fThermal Expansion RF§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fResonant Engine Coulombs§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Converts power from other mods to the internal energy type. Conversion rates:", + "oc:tooltip.powerdistributor": "Distributes energy among different networks. This is useful for sharing power fed into your system from one converter among different sub-networks that should remain separate.", + "oc:tooltip.present": "... for your troubles. Open this present for a chance to receive some §kphat lewt§7!\n§8Craft OpenComputers items when the time is right for a chance to receive a present.§7", + "oc:tooltip.print.BeaconBase": "§8Works as a beacon base.", + "oc:tooltip.print.LightValue": "§8Light emitted: %s.", + "oc:tooltip.print.RedstoneLevel": "§8Redstone output: %s.", + "oc:tooltip.printedcircuitboard": "The basic building block for expansion cards and memory and such.", + "oc:tooltip.printer": "Allows printing blocks of user-defined shapes using Chamelium and Ink Cartridges. Must be configured using a computer. Keep away from small children. Because reasons.", + "oc:tooltip.raid": "Allows combining three hard drives into one larger file system that can be used by all connected computers.", + "oc:tooltip.rawcircuitboard": "Can be hardened in any furnace compatible oven.", + "oc:tooltip.redstone": "Allows reading and emitting redstone signals around the block. Can be controlled by any computer the block is connected to. This is basically like an external redstone card.", + "oc:tooltip.redstonecard.Charset": "§fSimpleLogic§7 is §asupported§7.", + "oc:tooltip.redstonecard.ProjectRed": "§fProjectRed§7 is §asupported§7.", + "oc:tooltip.redstonecard.RedLogic": "§fRedLogic§7 is §asupported§7.", + "oc:tooltip.redstonecard.RedNet": "§fRedNet§7 is §asupported§7.", + "oc:tooltip.redstonecard.WirelessCBE": "§fWireless Redstone (ChickenBones)§7 is §asupported§7.", + "oc:tooltip.redstonecard.WirelessSV": "§fWireless Redstone (SlimeVoid)§7 is §asupported§7.", + "oc:tooltip.redstonecard": "Allows reading and emitting redstone signals around the computer or robot.", + "oc:tooltip.relay": "Allows connecting different networks to each other. Only network messages will be passed along, components will not be visible through this. Use this to separate networks while still allowing communication using Network Cards, for example.", + "oc:tooltip.robot": "Unlike computers, robots can move around and interact with the world much like a player can.\n§cCan not connect to external components.§7", + "oc:tooltip.robot_level": "§fLevel§7: §a%s§7", + "oc:tooltip.robot_storedenergy": "§fStored energy§7: §a%s§7", + "oc:tooltip.screen": "Display text, controlled by a Graphics Card in a Case.\nMaximum resolution: §f%sx%s§7\nMaximum color depth: §f%s§7", + "oc:tooltip.server": "This is a server, there are many like it, but this one can be upgraded with components much like a computer case can be. It can be run by inserting it into a server rack.", + "oc:tooltip.server.Components": "Installed components:", + "oc:tooltip.rack": "Allows the installation of up to four servers or other rack mountables.", + "oc:tooltip.tablet": "A tablet computer, for fresh Lua on the go. Can be forced to shut down by sneak-activating it.", + "oc:tooltip.tabletcase": "Basic case for tablets. Place it into the assembler to add in components and create a tablet computer.", + "oc:tooltip.terminal": "Allows controlling a server remotely, as long as you are in range of it. Acts like a portable screen and keyboard. Shift-right-click a server in a server rack to bind the terminal to it.", + "oc:tooltip.terminalserver": "Backend to which Remote Terminals can be connected to provide remote control. Houses a virtual screen and keyboard.", + "oc:tooltip.texturepicker": "This tool allows showing a string describing a block's surface, for use in 3D printer shape definitions. Totally not texture names, nope. No sir.", + "oc:tooltip.tier": "§8Tier %s", + "oc:tooltip.netsplitter": "Acts as a dynamic connector. Connectivity of each side can be toggled by hitting it with a wrench. Connectivity of all sides can be inverted by applying a redstone signal.", + "oc:tooltip.toolong": "Hold [§f%s§7] for a detailed tooltip.", + "oc:tooltip.transistor": "A basic element in most other computer parts. It's a bit twisted, but it does the job.", + "oc:tooltip.transposer": "Allows automated transferral of items and fluids between adjacent inventories and fluid containers.", + "oc:tooltip.upgradeangel": "Allows robots to place blocks in thin air, even if there is no point of reference.", + "oc:tooltip.upgradebattery": "Increase the amount of energy a device can store, allowing it work longer without having to be recharged.\nCapacity: §f%s§7", + "oc:tooltip.upgradechunkloader": "If a robot moves in a forest and no one is around to see it, does it really move? This upgrades makes sure it does. It keeps the chunk a device is in loaded, but continually consumes energy while active.", + "oc:tooltip.upgradecontainercard": "This container upgrade allows dynamically installing and removing a card from an assembled device.\nMaximum Tier: §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "This container upgrade allows dynamically installing and removing another upgrade from an assembled device.\nMaximum Tier: §f%s§7", + "oc:tooltip.upgradecrafting": "Enables robots to use the top left area of their inventory for crafting objects. Items have to be aligned as they would be in a crafting table.", + "oc:tooltip.upgradedatabase": "This upgrade allows storing item stack information for later retrieval and use by other components.\nSupported entries: §f%s§7", + "oc:tooltip.upgradeexperience": "This upgrade allows robots to accumulate experience by performing various operations. The more experience they have, the more energy they can store, the faster they can harvest blocks and the more efficiently they can use tools.", + "oc:tooltip.upgradegenerator": "Can be used to generate energy from fuel on the go. Burns items to generate energy over time, based on their fuel value.\n§fEfficiency§7: §a%s%%§7", + "oc:tooltip.upgradehover": "This upgrade allows robots to fly higher above the ground without having to climb walls.\nMaximum height: §f%s§7", + "oc:tooltip.upgradeinventory": "This upgrade provides inventory space to a robot or drone. Without one of these, they will not be able to store items internally.", + "oc:tooltip.upgradeinventorycontroller": "This upgrade allows robots and drones more control in how it interact with external inventories, and allows robots to swap their equipped tool with an item in their inventory.", + "oc:tooltip.upgrademf": "Allows adapters to access blocks they are not adjacent to.", + "oc:tooltip.upgrademf.Linked": "§fConnection established§7", + "oc:tooltip.upgrademf.Unlinked": "§fNo connection§7", + "oc:tooltip.upgradeleash": "Allows some devices, such as drones, to bind Isaa- excuse me... *chatter* My apologies. I'm just being told this is actually used to put animals on a leash. Multiple animals, even. Odd.", + "oc:tooltip.upgradenavigation": "Can be used to determine the position and orientation of a device. The position is relative to the center of the map that was used to craft this upgrade.", + "oc:tooltip.upgradepiston": "This upgrade is very pushy. It allows moving blocks, similar to a piston.", + "oc:tooltip.upgradestickypiston": "This upgrade can push and pull. It allows moving blocks, similar to a sticky piston. It does §lnot§7 pull entities, however.", + "oc:tooltip.upgradesign": "Allows reading text on and writing text to signs.", + "oc:tooltip.upgradesolargenerator": "Can be used to generate energy from sunlight on the go. Requires a clear line of sight to the sky above the device. Generates energy at %s%% of the speed of a Stirling Engine.", + "oc:tooltip.upgradetank": "This upgrade provides a tank for fluid storage for robots and drones. Without one of these, they will not be able to store fluids internally.", + "oc:tooltip.upgradetankcontroller": "This upgrade allows robots and drones more control in how they interact with external tanks, and allows them to transfer fluids into and out of fluid tank items in their inventory.", + "oc:tooltip.upgradetractorbeam": "Equips a device with extremely advanced technology, nicknamed the \"Item Magnet\". Allows the device to pick up items anywhere within 3 blocks of its location.", + "oc:tooltip.upgradetrading": "Allows robots and drones to trade with villagers.", + "oc:tooltip.waypoint": "Provides a point of reference to devices with a navigation upgrade.", + "oc:tooltip.wirelessnetworkcard": "Allows wireless sending of network messages in addition to normal ones. You can adjust the §fsignal strength§7 to control how far messages are sent. Higher signal strength results in higher energy consumption.", + "oc:tooltip.worldsensorcard": "Allows reading out information about the world, such as its gravity and whether it has a breathable atmosphere. Use results at own risk. The manufacturer takes no responsibility for bodily or material harm caused by decisions made upon the cards' outputs. We have lawyers. And money. Don't even try.", + "oc:tooltip.Wrench": "A hybrid of Screwdriver and Wrench, this tool is easy to learn, but hard to master.", + "achievement.oc.adapter": "Plug In Baby", + "achievement.oc.adapter.desc": "Interact with blocks from other mods and even vanilla Minecraft!", + "achievement.oc.assembler": "Wonderful", + "achievement.oc.assembler.desc": "Time to take over the world!", + "achievement.oc.cable": "Not a Dirty Wire", + "achievement.oc.cable.desc": "With patented anti-cable-spaghetti technology.", + "achievement.oc.capacitor": "Batteries included", + "achievement.oc.capacitor.desc": "You cannot stop it.", + "achievement.oc.card": "We Accept Cards", + "achievement.oc.card.desc": "For your convenience. No ulterior motive, promise.", + "achievement.oc.case": "In Case of Trouble", + "achievement.oc.case.desc": "Because cuboid towers are the best.", + "achievement.oc.charger": "All right, let's do this", + "achievement.oc.charger.desc": "Chaaaaaaaaaarg- dang, forgot the redstone signal again.", + "achievement.oc.chip": "All the Small Things", + "achievement.oc.chip.desc": "Because vacuum tubes are so yesteryear.", + "achievement.oc.cpu": "Overclocked", + "achievement.oc.cpu.desc": "Time to make good use of those computing cycles.", + "achievement.oc.disassembler": "Scratch That", + "achievement.oc.disassembler.desc": "In case one of your brilliant ideas turns out to be not that brilliant after all.", + "achievement.oc.diskDrive": "Roundabout", + "achievement.oc.diskDrive.desc": "Inferior capacity but such delicious sound.", + "achievement.oc.drone": "Fly Away", + "achievement.oc.drone.desc": "Keep calm and nuke it from orbit.", + "achievement.oc.eeprom": "There can be only one", + "achievement.oc.eeprom.desc": "Per computer, that is. For deterministic boot order, you know?", + "achievement.oc.floppy": "The One Ri- Disk", + "achievement.oc.floppy.desc": "Not to be confused with Flappy.", + "achievement.oc.geolyzer": "Down to Earth", + "achievement.oc.geolyzer.desc": "It has extraordinary qualities.", + "achievement.oc.graphicsCard": "LastGen", + "achievement.oc.graphicsCard.desc": "The way it's meant to be... uh... rendered. Yeah. That.", + "achievement.oc.hdd": "Hot Dog Dealer", + "achievement.oc.hdd.desc": "No wait, that's not what that meant. Hang on, almost got it...", + "achievement.oc.hologram": "Next Dimension", + "achievement.oc.hologram.desc": "Because 2D is boring. Or is it?", + "achievement.oc.keyboard": "DirtCatcher3000", + "achievement.oc.keyboard.desc": "It is highly recommended to resist the urge to flip them around and shake them.", + "achievement.oc.microcontroller": "Little Sister", + "achievement.oc.microcontroller.desc": "The small sibling of computers.", + "achievement.oc.motionSensor": "Got the Moves", + "achievement.oc.motionSensor.desc": "Like Steve Swagger.", + "achievement.oc.networkCard": "Now We're Talking!", + "achievement.oc.networkCard.desc": "Keep in touch with those distant relatives via transitive relations.", + "achievement.oc.openOS": "Boot", + "achievement.oc.openOS.desc": "One OS to - wait, I used that one already? Dang.", + "achievement.oc.powerDistributor": "Sharing is Caring", + "achievement.oc.powerDistributor.desc": "When you need some help balancing all that power.", + "achievement.oc.rack": "Dat Rack", + "achievement.oc.rack.desc": "I don't know what you're thinking of, I clearly meant the server rack.", + "achievement.oc.raid": "LFG", + "achievement.oc.raid.desc": "Heroic plzkthx.", + "achievement.oc.ram": "Random Access Memories", + "achievement.oc.ram.desc": "Congratulations, you're Doin' It Right.", + "achievement.oc.redstoneCard": "Contact", + "achievement.oc.redstoneCard.desc": "Time to go analog.", + "achievement.oc.redstoneIO": "The Outsider", + "achievement.oc.redstoneIO.desc": "Taking redstone signals where you want them.", + "achievement.oc.robot": "Beep Boop", + "achievement.oc.robot.desc": "EXTERMINATE!", + "achievement.oc.screen": "Have you tried turning it off and on again?", + "achievement.oc.screen.desc": "No seriously. A redstone pulse can toggle a screen's power, after all.", + "achievement.oc.server": "Dedicated", + "achievement.oc.server.desc": "Cloud services, here we come.", + "achievement.oc.switch": "Complex Topology", + "achievement.oc.switch.desc": "Avoid fragile goods due to possibility of dropped packets.", + "achievement.oc.tablet": "Do Not Swallow", + "achievement.oc.tablet.desc": "Also keep away from small children to avoid unexpected overdrawing of your credit card.", + "achievement.oc.transistor": "Tell Red I said \"Hi.\"", + "achievement.oc.transistor.desc": "Create a Transistor to get started. Then listen to the soundtrack. No need to thank me.", + "achievement.oc.wirelessNetworkCard": "Signals", + "achievement.oc.wirelessNetworkCard.desc": "Time to go where no packet has gone before.", + "death.attack.oc.nanomachinesOverload.1": "%s got too greedy.", + "death.attack.oc.nanomachinesOverload.2": "%s had a nervous breakdown.", + "death.attack.oc.nanomachinesOverload.3": "The nanomachines of %s went out of control.", + "death.attack.oc.nanomachinesHungry.1": "%s was eaten by nanomachines.", + "death.attack.oc.nanomachinesHungry.2": "%s didn't keep their nanomachines fed.", + "death.attack.oc.nanomachinesHungry.3": "%s has been digested.", + "nei.options.inventory.oredict": "Show OreDictionary names", + "nei.options.inventory.oredict.true": "True", + "nei.options.inventory.oredict.false": "False", + "nei.usage.oc.Manual": "Open Manual", + "option.oc.address": "Address", + "option.oc.componentName": "Component Name", + "option.oc.energy": "Energy" +} diff --git a/src/main/resources/assets/opencomputers/lang/fr_FR.lang b/src/main/resources/assets/opencomputers/lang/fr_FR.lang deleted file mode 100644 index eac2d692d2..0000000000 --- a/src/main/resources/assets/opencomputers/lang/fr_FR.lang +++ /dev/null @@ -1,359 +0,0 @@ -# Blocks, items, gui, containers, keybinds and tooltips only -# -# - -# Blocks -tile.oc.accesspoint.name=Point d'accès -tile.oc.adapter.name=Adaptateur -tile.oc.assembler.name=Assembleur électronique -tile.oc.cable.name=Câble -tile.oc.capacitor.name=Capaciteur -tile.oc.case1.name=Boitier (Niveau 1) -tile.oc.case2.name=Boitier (Niveau 2) -tile.oc.case3.name=Boitier (Niveau 3) -tile.oc.casecreative.name=Boitier (Créatif) -tile.oc.chameliumblock.name=Bloc de Chamélium -tile.oc.charger.name=Chargeur -tile.oc.disassembler.name=Désassembleur -tile.oc.diskdrive.name=Lecteur de disquettes -tile.oc.endstone.name=Pierre du néant -tile.oc.geolyzer.name=Géoliseur -tile.oc.hologram1.name=Projecteur d'hologramme (Niveau 1) -tile.oc.hologram2.name=Projecteur d'hologramme (Niveau 2) -tile.oc.keyboard.name=Clavier -tile.oc.microcontroller.name=Micro-contrôleur -tile.oc.motionsensor.name=Détecteur de mouvement -tile.oc.netsplitter.name=Répartiteur réseau -tile.oc.powerconverter.name=Convertisseur énergétique -tile.oc.powerdistributor.name=Distributeur énergétique -tile.oc.print.name=Impression 3D -tile.oc.printer.name=Imprimante 3D -tile.oc.raid.name=Raid -tile.oc.redstone.name=Redstone E/S -tile.oc.relay.name=Relai -tile.oc.robot.name=Robot -tile.oc.robotafterimage.name=Robot -tile.oc.screen1.name=Ecran (Niveau 1) -tile.oc.screen2.name=Ecran (Niveau 2) -tile.oc.screen3.name=Ecran (Niveau 3) -tile.oc.rack.name=Support de serveur -tile.oc.switch.name=Routeur -tile.oc.transposer.name=Transposeur -tile.oc.waypoint.name=Point de passage - -# Items -item.oc.abstractbuscard.name=Carte de bus abstraite -item.oc.acid.name=Grog -item.oc.alu.name=Unité de Logique Arithmétique (ULA) -item.oc.analyzer.name=Analyseur -item.oc.apu0.name=Unité de Traitement Accélérée (UTA) (Niveau 1) -item.oc.apu1.name=Unité de Traitement Accélérée (UTA) (Niveau 2) -item.oc.apu2.name=Unité de Traitement Accélérée (UTA) (Créatif) -item.oc.arrowkeys.name=Touches directionnelles -item.oc.buttongroup.name=Groupe de boutons -item.oc.cardbase.name=Base de carte -item.oc.chamelium.name=Chamélium -item.oc.circuitboard.name=Plaque de circuit imprimé -item.oc.componentbus0.name=Bus des composants (Niveau 1) -item.oc.componentbus1.name=Bus des composants (Niveau 2) -item.oc.componentbus2.name=Bus des composants (Niveau 3) -item.oc.controlunit.name=Unité de contrôle (UC) -item.oc.cpu0.name=Processeur (Niveau 1) -item.oc.cpu1.name=Processeur (Niveau 2) -item.oc.cpu2.name=Processeur (Niveau 3) -item.oc.cuttingwire.name=Fil de coupe -item.oc.debugcard.name=Carte de débogueur -item.oc.debugger.name=Débogueur réseau -item.oc.disk.name=Disque -item.oc.drone.name=Drone -item.oc.dronecase0.name=Boitier de drone (Niveau 1) -item.oc.dronecase1.name=Boitier de drone (Niveau 2) -item.oc.dronecase3.name=Boitier de drone (Créatif) -item.oc.eeprom.name=EEPROM -item.oc.floppydisk.name=Disquette -item.oc.graphicscard0.name=Carte graphique (Niveau 1) -item.oc.graphicscard1.name=Carte graphique (Niveau 2) -item.oc.graphicscard2.name=Carte graphique (Niveau 3) -item.oc.harddiskdrive0.name=Disque dur (Niveau 1) -item.oc.harddiskdrive1.name=Disque dur (Niveau 2) -item.oc.harddiskdrive2.name=Disque dur (Niveau 3) -item.oc.hoverboots.name=Bottes de vol plané -item.oc.inkcartridge.name=Cartouche d'encre -item.oc.inkcartridgeempty.name=Cartouche d'encre (Vide) -item.oc.internetcard.name=Carte internet -item.oc.interweb.name=Interweb -item.oc.ironnugget.name=Pépite de fer -item.oc.linkedcard.name=Carte liée -item.oc.manual.name=Manuel d'OpenComputers -item.oc.memory0.name=Mémoire (Niveau 1) -item.oc.memory1.name=Mémoire (Niveau 1.5) -item.oc.memory2.name=Mémoire (Niveau 2) -item.oc.memory3.name=Mémoire (Niveau 2.5) -item.oc.memory4.name=Mémoire (Niveau 3) -item.oc.memory5.name=Mémoire (Niveau 3.5) -item.oc.microchip0.name=Puce électronique (Niveau 1) -item.oc.microchip1.name=Puce électronique (Niveau 2) -item.oc.microchip2.name=Puce électronique (Niveau 3) -item.oc.microcontrollercase0.name=Boitier de microcontrôleur (Niveau 1) -item.oc.microcontrollercase1.name=Boitier de microcontrôleur (Niveau 2) -item.oc.microcontrollercase3.name=Boitier de microcontrôleur (Créatif) -item.oc.networkcard.name=Carte réseau -item.oc.numpad.name=Pavé numérique -item.oc.present.name=Un petit quelque chose... -item.oc.printedcircuitboard.name=Circuit imprimé -item.oc.rawcircuitboard.name=Plaque de circuit imprimé brute -item.oc.redstonecard0.name=Carte de Redstone (Niveau 1) -item.oc.redstonecard1.name=Carte de Redstone (Niveau 2) -item.oc.server0.name=Serveur (Niveau 1) -item.oc.server1.name=Serveur (Niveau 2) -item.oc.server2.name=Serveur (Niveau 3) -item.oc.server3.name=Serveur (Créatif) -item.oc.tablet.name=Tablette -item.oc.tabletcase.name=Boitier de tablette (Niveau 1) -item.oc.tabletcase.name=Boitier de tablette (Niveau 2) -item.oc.tabletcase.name=Boitier de tablette (Créatif) -item.oc.terminal.name=Terminal à distance -item.oc.texturepicker.name=Ramasseur de texture -item.oc.transistor.name=Transistor -item.oc.upgradeangel.name=Amélioration ange -item.oc.upgradebattery0.name=Amélioration batterie (Niveau 1) -item.oc.upgradebattery1.name=Amélioration batterie (Niveau 2) -item.oc.upgradebattery2.name=Amélioration batterie (Niveau 3) -item.oc.upgradechunkloader.name=Amélioration chargement de chunk -item.oc.upgradecontainercard0.name=Conteneur de carte (Niveau 1) -item.oc.upgradecontainercard1.name=Conteneur de carte (Niveau 2) -item.oc.upgradecontainercard2.name=Conteneur de carte (Niveau 3) -item.oc.upgradecontainerupgrade0.name=Amélioration de conteneur (Niveau 1) -item.oc.upgradecontainerupgrade1.name=Amélioration de conteneur (Niveau 2) -item.oc.upgradecontainerupgrade2.name=Amélioration de conteneur (Niveau 3) -item.oc.upgradecrafting.name=Amélioration d'artisanat -item.oc.upgradedatabase0.name=Amélioration de base de données (Niveau 1) -item.oc.upgradedatabase1.name=Amélioration de base de données (Niveau 2) -item.oc.upgradedatabase2.name=Amélioration de base de données (Niveau 3) -item.oc.upgradeexperience.name=Amélioration d'expérience -item.oc.upgradegenerator.name=Amélioration de générateur -item.oc.upgradehover0.name=Amélioration de vol plané (Niveau 1) -item.oc.upgradehover1.name=Amélioration de vol plané (Niveau 2) -item.oc.upgradeinventory.name=Amélioration d'inventaire -item.oc.upgradeinventorycontroller.name=Amélioration du contrôleur d'inventaire -item.oc.upgradeleash.name=Amélioration de laisse -item.oc.upgradenavigation.name=Amélioration de navigation -item.oc.upgradepiston.name=Amélioration de piston -item.oc.upgradesign.name=Amélioration de panneau d'E/S -item.oc.upgradesolargenerator.name=Amélioration du générateur solaire -item.oc.upgradetank.name=Amélioration de réservoir -item.oc.upgradetankcontroller.name=Amélioration du contrôleur de réservoir -item.oc.upgradetractorbeam.name=Amélioration du rayon tracteur -item.oc.wirelessnetworkcard0.name=Carte de réseau sans-fils (Niveau 1) -item.oc.wirelessnetworkcard1.name=Carte de réseau sans-fils (Niveau 2) -item.oc.worldsensorcard.name=Carte de capteur du monde -item.oc.wrench.name=Crisseur - -# Entities -entity.oc.Drone.name=Drone - -# GUI -oc:gui.Analyzer.Address=§6Addresse§f: %s -oc:gui.Analyzer.AddressCopied=Adresse copiée dans le presse-papier. -oc:gui.Analyzer.ChargerSpeed=§6Vitesse de charge§f: %s -oc:gui.Analyzer.ComponentName=§6Nom du composant§f: %s -oc:gui.Analyzer.Components=§6Nombre de composants connectés§f: %s -oc:gui.Analyzer.LastError=§6Dernière erreur§f: %s -oc:gui.Analyzer.RobotName=§6Nom§f: %s -oc:gui.Analyzer.RobotOwner=§6Propriétaire§f: %s -oc:gui.Analyzer.RobotXp=§6Expérience§f: %s -oc:gui.Analyzer.StoredEnergy=§6Energie stockée§f: %s -oc:gui.Analyzer.TotalEnergy=§6Energie totale§f: %s -oc:gui.Analyzer.Users=§6Utilisateurs§f: %s -oc:gui.Analyzer.WirelessStrength=§6Force du signal§f: %s -oc:gui.Assembler.Collect=Collectez la sortie -oc:gui.Assembler.Complexity=Complexité: %s/%s -oc:gui.Assembler.InsertCase=Insérez une partie de base -oc:gui.Assembler.InsertCPU=Insérez une UCP -oc:gui.Assembler.InsertRAM=Insérez un peu de mémoire -oc:gui.Assembler.Progress=Progression: %s%% (%s) -oc:gui.Assembler.Run=Assemble -oc:gui.Assembler.Warning.BIOS=BIOS -oc:gui.Assembler.Warning.GraphicsCard=Carte graphique -oc:gui.Assembler.Warning.Inventory=Amélioration d'inventaire -oc:gui.Assembler.Warning.Keyboard=Clavier -oc:gui.Assembler.Warning.OS=Moyen de démarrage -oc:gui.Assembler.Warning.Screen=Ecran -oc:gui.Assembler.Warnings=§eALERTE§7: Les composants recommandés sont manquant. -oc:gui.Chat.NewVersion=une nouvelle version est disponible: %s -oc:gui.Chat.TextureName=§7Le nom de la texture est §a%s§f. -oc:gui.Chat.WarningClassTransformer=Il y a §cerrors§f lancement dans le transformeur de classe. Veuillez vérifier ceci, en même temps que votre fichier log (plein) FML §alatest.log§f/§afml-server-latest.log§f, Merci ! -oc:gui.Chat.WarningFingerprint=§cALERTE§f - Disparité d'empreinte digitale! Attendu '§a%s§f' mais eu '§e%s§f'. À moins que vous ne soyez un modder et que vous exécutiez la version deobfuscated du mod, Il est §lfortement§f recommendé de re-télécharger OpenComputers, parce que le JAR que vous utilisez peut avoir été falsifié. -oc:gui.Chat.WarningLink=Impossible d'ouvrir le lien : %s -oc:gui.Chat.WarningLuaFallback=Les bibliothèques natives Lua ne sont pas disponibles, les ordinateurs ne pourront pas persister en leur état. Ils réamorceront sur la recharge des chunks. -oc:gui.Chat.WarningProjectRed=Vous utilisez une version de Project: Red qui est incompatible avec OpenComputers. Essayez de mettre à jour votre version de Project: Red. -oc:gui.Chat.WarningRecipes=il y a des erreurs au lancement de recettes. Certains éléments doivent être infabricables. Veuillez vérifier votre fichier log pour plus d'information. -oc:gui.Chat.WarningSimpleComponent=Un ajout (le votre ?) utilisant l'interface §aComposant Simple§f produit §equelquechose de mauvais§f. Le composant logique ne peut être inséré. Veuillez vérifier votre fichier log pour plus d'information. -oc:gui.Error.ComponentOverflow=Beaucoup trop de composants connectés à l'ordinateur. -oc:gui.Error.InternalError=Erreur interne, Veuillez lire le fichier log. Ceci est probablement une erreur. -oc:gui.Error.NoCPU=Pas d'UCP installé dans cet ordinateur. -oc:gui.Error.NoEnergy=Pas assez d'énergie. -oc:gui.Error.NoRAM=pas de mémoire installée dans cet ordinateur. -oc:gui.Error.OutOfMemory=Mémoire saturée. -oc:gui.Manual.Blocks=Blocs d'OpenComputers -oc:gui.Manual.Home=Accueil -oc:gui.Manual.Items=Éléments d'OpenComputers -oc:gui.Manual.Warning.BlockMissing=Bloc manquant. -oc:gui.Manual.Warning.ImageMissing=Image manquante. -oc:gui.Manual.Warning.ItemMissing=Élément manquant. -oc:gui.Manual.Warning.OreDictMissing=Entrée au dictionnaire de minerai manquante. -oc:gui.Raid.Warning=§4L'ajout d'un disque le nettoie.[nl] L'enlèvement d'un disque nettoie le raid. -oc:gui.Robot.Power=Énergie -oc:gui.Robot.TurnOff=Éteindre -oc:gui.Robot.TurnOn=Allumer -oc:gui.Rack.None=Aucun -oc:gui.Rack.Back=Arrière -oc:gui.Rack.Bottom=Bas -oc:gui.Rack.Left=Gauche -oc:gui.Rack.Right=Droite -oc:gui.Rack.Top=Haut -oc:gui.Switch.TransferRate=Vitesse du cycle -oc:gui.Switch.PacketsPerCycle=paquets / cycle -oc:gui.Switch.QueueSize=Taille de la file -oc:gui.Terminal.InvalidKey=Clef invalide, très probablement qu'un autre terminal a dû nécessité le serveur. -oc:gui.Terminal.OutOfRange=Pas de signal. - -# Containers -oc:container.accesspoint=Point d'accès -oc:container.adapter=Adapteur -oc:container.case=Ordinateur -oc:container.charger=Chargeur -oc:container.disassembler=Désassembleur -oc:container.diskdrive=Lecteur disque -oc:container.printer=Imprimante -oc:container.raid=Raid -oc:container.server=Serveur -oc:container.rack=Support de serveur -oc:container.switch=Routeur -oc:container.tabletwrapper=Tablette - -# Keybinds -key.materialCosts=Montrer les coût en matériaux -key.clipboardPaste=Coller le presse-papier - -# Item / Block Tooltips -oc:tooltip.accesspoint=Fonctionne comme un routeur, de plus il recois les paquets sans-fil et il transmet les paquets filaires au réseau sans-fil. -oc:tooltip.abstractbuscard=Il permet d'interagir avec le bus abstait de §fStargateTech 2§7 lors de l'envoi et de la reception de paquets LIP. -oc:tooltip.acid=Un produit semi-liquide très toxique, uniquement bu par certains pirates. Grâce à ses propriétés corrosives, il est très utile à la gravure de circuits imprimés. -oc:tooltip.adapter=Utilisé pour contrôler des blocs n'étant pas des composants d'ordinateurs, comme des blocs Vanilla ou d'autres mods. -oc:tooltip.alu=Ajoute des nombres pour que vous n'ayez pas à le faire. C'est peut-être mieux comme ça. -oc:tooltip.analyzer=Utilisé pour afficher des informations sur des blocs, comme leur §faddresse§7 et leur §fnom de composant§7.[nl] Affiche aussi les erreurs en cas de crash d'un ordinateur. -oc:tooltip.apu=Ceci est une UTC avec une UTG intégrée (ou UTI), lorsque vous avez juste besoin d'un emplacement de carte supplémentaire.[nl] Composants supportés : §f%s§7[nl] Résolution maximum: §f%sx%s§7[nl] profondeur de couleur maxi: §f%s§7[nl] Opérations/tic: §f%s§7 -oc:tooltip.assembler=Il permet de construire des robots et d'autres dispositifs d'un certain nombre de pièces informatiques différentes. -oc:tooltip.cable=Un moyen peu coûteux pour relier les ordinateurs entre eux. -oc:tooltip.capacitor=Stocke l'énergie pour une utilisation ultérieure. Peut être chargé et déchargé très rapidement. -oc:tooltip.cardbase=Comme son nom l'indique, c'est le bloc de construction basique pour toutes les cartes. -oc:tooltip.case=La tour est le bloc principal de l'ordinateur, et héberge ses §fcartes§7, sa §fMémoire RAM§7 et ses §fdisques durs§7.[nl] Emplacements: §f%s§7 -oc:tooltip.chamelium=Matière première pour impression 3D. Ne pas avaler : Peut mener à la cécité et au manque de présence provisoire. -oc:tooltip.chameliumblock=Joli et propre. Pratique pour formes teintées dans les impressions 3D, ou juste pour avoir un bloc propre, coloré, pour décorer votre base fantaisiste avec. -oc:tooltip.charger=Transfère l'énergie depuis des capaciteurs pour les robots adjacents. La puissance du transfert dépends du §fsignal de redstone§7, ou une absence de signal ne charge pas les robots, et un signal maximum charge les robots le plus vite possible. -oc:tooltip.circuitboard=Hé ben, on y arrive. Peut être gravé pour obtenir un circuit imprimé. -oc:tooltip.controlunit=C'est une unité qui... controle... des trucs. On en a besoin pour faire un processeur. Donc, ouais, super important. -oc:tooltip.componentbus=Cette extention autorise aux serveurs de communiquer avec plus composants en même temps, Semblable à ce que les UCP font.[nl] Composants supportés : §f%s§7 -oc:tooltip.cpu=Un composant essentiel pour tout ordinateur. La fréquence d'horloge est un peu douteuse, mais, vous vous attendiez à quoi avec un cadran solaire de poche ? -oc:tooltip.cpu.Architecture=Architecture: §f%s§7 -oc:tooltip.cuttingwire=Utilisé pour couper des blocs d'argile en plaque de circuit imprimé. Se casse après utilisation, ce qui rends cet outil le moins efficace jamais utilisé. -oc:tooltip.debugcard=Element en mode créatif, il autorise la manipulation du monde pour faciliter les tests. Utilisation à votre propre péril. -oc:tooltip.debugger=Peut être utilisé pour sortir les information de débogue sur la grille réseau interne de OC. A utiliser seulement si instruit par un dev. -oc:tooltip.disassembler=Sépare les éléments dans leur composants d'origine. §lAttention§7: les éléments ainsi récupérés ont %s%% de chance de ce briser dans le processus ! -oc:tooltip.disk=Moyen primitif qui peut être utilisé pour faire des appareils de stockage persistants. -oc:tooltip.diskdrive.CC=Les disquettes ComputerCraft sont §asupportées§7. -oc:tooltip.diskdrive=Permet de lire et d"écrire des disquettes. Peut être installé dans les robots pour permettre d'insérer des disquettes plus tard. -oc:tooltip.drone=Les drones sont de légère unité de reconnaissance rapide avec un espace de chargement limité. -oc:tooltip.dronecase=Ce boitier est utilisé pour construire des Drones dans l'assembleur. Il a des emplacement pour une petite quantité de composant et fournit la lévitation en pierre de néant alimentée. -oc:tooltip.eeprom=Petit, stockage programmable qui contient le BIOS que les ordinateurs utilisent pour démarrer. -oc:tooltip.fakeendstone=Presque aussi bon que la chose réelle, imite même sa flottabilité ! -oc:tooltip.geolyzer=Permet de scanner la dureté des blocs des environs. Ces informations peuvent être utiles pour produire un hologramme de la zone ou pour détecter les minerais. -oc:tooltip.graphicscard=Utilisé pour changer ce qui est affiché sur écran.[nl] Résolution maximum: §f%sx%s§7[nl] Couleurs maximales: §f%s§7[nl] Operations/tick: §f%s§7 -oc:tooltip.hoverboots=Sautez plus haut, tombez plus bas, marchez mieux. Ceci et plus, avec les nouvelles Bottes de vol plané (TM). -oc:tooltip.inkcartridge=Utilisé pour remplir d'encre les imprimantes 3D. Pour des raisons mystérieuses, elle ne doit pas rester dans l'imprimante. -oc:tooltip.inkcartridgeempty=Cette cartouche d'encre a été vidé totalement. Remplissez la avec des couleurs. Ou jetez la. Voyez comme je m'en soucie. -oc:tooltip.internetcard=Cette carte permet de faire des requêtes HTTP et utiliser de véritable TCP sockets. -oc:tooltip.interweb=Félicitation, vous avez gagné un (1) interweb. Vous pouvez y connecter en utilisant une carte internet. Prenez garde : n'alimentez pas les trolls. -oc:tooltip.ironnugget=Une pépite de fer. D'où son nom. -oc:tooltip.keyboard=Peut être attaché à un écran pour permettre la saisie. -oc:tooltip.hologram0=Un affichage volumétrique qui peut être contrôlé par des ordinateurs pour montrer des structures de voxel arbitraires.[nl] Résolution : §f48x32x48§7 [nl] Echelle maxi : §f3x§7 [nl] Colorimétrie : §fMonochrome§7 -oc:tooltip.hologram1=Un affichage volumétrique qui peut être contrôlé par des ordinateurs pour montrer des structures de voxel arbitraires.[nl] Résolution : §f48x32x48§7 [nl] Echelle maxi : §f4x§7 [nl] Colorimétrie : §fTricolore§7 -oc:tooltip.linkedcard=Elles sont fabriqué par paire et ne peuvent communiquer qu'avec leur Carte partenaire. Cependant, elles peuvent communiquer à travers n'importe quelle distance et même à travers les dimensions. L'énergie exigée pour envoyer un message est assez haute malgès tout. -oc:tooltip.linkedcard_channel=§8Canal : %s§7 -oc:tooltip.manual=Toutes les informations vous pourriez probablement avoir besoin sur OpenComputers. Et plus. Au prix incroyablement bas de... §oveuillez appuyer sur R pour continuer§7. -oc:tooltip.materialcosts=Prend [§f%s§7] pour les coûts des matériaux. -oc:tooltip.materials=Materiaux : -oc:tooltip.memory=Requis pour faire fonctionner les ordinateurs. Plus vous en avez, plus complexes les programmes seront utilisables. -oc:tooltip.microchip=La puce anciennement circuit intégré. J'ai aucune idée du comment ça marche avec la redstone, mais ça marche. -oc:tooltip.microcontroller=Les microcontrôleurs sont des ordinateurs résumés à l'essentiel. Ils sont destinés pour s'occuper de tâches très spécifiques, dirigant seulement l'unique programme que lui donne l'EEPROM qu'il intègre. -oc:tooltip.microcontrollercase=Composant de base pour construire des microcontrôleurs. Placez-le dans un assembleur pour ajouter de nouveaux composants et assemblez un microcontrôleur. -oc:tooltip.motionsensor=Peut détecter le mouvement d'êtres vivants à proximité. Demande une ligne de vue dégagée. -oc:tooltip.networkcard=Permet à des ordinateurs distants de communiquer en s'envoyant des messages. -oc:tooltip.poweracceptor=Vitesse de convertion d'énergie: §f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§fBuildCraft en MJ§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§fCharges de Factorization§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fIndustrialCraft² en EU§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§fMekanism en Joules§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fThermal Expansion en RF§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fResonant Engine en Coulombs§7: §a%s:%s§7 -oc:tooltip.powerconverter=Convertis l'énergie d'autres mods en l'énergie requise pour faire fonctionner les ordinateurs. -oc:tooltip.powerdistributor=Distribue l'énergie dans plusieurs réseaux. Utile pour partager cette énergie depuis un convertisseur vers différents sous-réseaux qui doivent rester séparés. -oc:tooltip.present=... pour vos ennuis. Ouvrez ce cadeau pour une chance de recevoir quelques éléments d'OpenCompucters §kpsorti du chapeaut§7![nl]§8 quand c'est le bon momment de recevoir un cadeau.§7 -oc:tooltip.print.BeaconBase=§8Fonctionne comme une base de balise. -oc:tooltip.print.LightValue=§8Lumière émise : %s. -oc:tooltip.print.RedstoneLevel=§8Sortie Redstone : %s. -oc:tooltip.printedcircuitboard=Le composant basique pour les cartes, la mémoire, etc. -oc:tooltip.raid=Permet de combiner trois disques durs dans un plus grand système de fichiers qui pourra être utilisé par tous les ordinateurs connectés. -oc:tooltip.rawcircuitboard=Peut être durci dans n'importe quel four. -oc:tooltip.redstone=Permet de recevoir et d'émettre des signaux de redstone autour du bloc. Contrôlable par n'importe quel ordinateur connecté à ce bloc. En gros, une carte redstone externe. -oc:tooltip.redstonecard.ProjectRed=§fProjectRed§7 est §asupporté7. -oc:tooltip.redstonecard.RedLogic=§fRedLogic§7 est §asupporté§7. -oc:tooltip.redstonecard.RedNet=§fRedNet§7 est §asupporté§7. -oc:tooltip.redstonecard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 est §asupporté§7. -oc:tooltip.redstonecard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 est §asupporté§7. -oc:tooltip.redstonecard=Permet la réception et l'émission de signaux de redstone autour de l'ordinateur ou du robot. -oc:tooltip.robot=Contrairement aux ordinateurs, les robots peuvent se déplacer et intéragir avec le monde comme un joueur le fait. Ils ne peuvent §opas§r§7 intéragir avec des composants d'ordinateur extérieurs, ceci dit ! -# the underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fNiveau§7: §a%s§7. -oc:tooltip.robot_storedenergy=§fEnergie stockée§7: §a%s§7. -oc:tooltip.screen=Affiche du texte, contrôlé par une Carte graphique dans un Boitier.[nl] Résolution maximum: §f%sx%s§7[nl] Couleurs maximales: §f%s§7 -oc:tooltip.server=Ceci est un serveur, il y en a beaucoup comme ca, mais celui-ci peut être amélioré avec des composants bien plus qu'un ordinateur peut l'être. Il peut être placé dans un support de serveur. -oc:tooltip.server.Components=Composants installés : -oc:tooltip.rack=Permet l'installation jusqu'à quatre serveurs. -oc:tooltip.switch=Permet de connecter différents réseaux entre eux. Seulement des messages réseau seront transmis, les composants ne seront pas visibles via celui ci. A utiliser pour séparer des réseaux tout en leur permettant de communiquer entre eux, grâce aux Cartes réseau, par exemple. -oc:tooltip.tablet=Une tablette, pour une Lua fraiche en route. Peut être forcé à l'arrêt par un accroupi-clique droit. -oc:tooltip.tabletcase=Boitier de tablettes de base. Placez-le dans l'assembleur pour ajouter des composants et créez une tablette. -oc:tooltip.terminal=Permet de contrôler un serveur à distance, tant que vous êtes à portée de lui. Fonctionne comme un écran-clavier portable. Maj-clique droit un serveur du support pour le lier au terminal. -oc:tooltip.tier=§8Niv. %s -oc:tooltip.toolong=Maintenez la touche [§f%s§7] pour plus d'informations. -oc:tooltip.transistor=Un élément basique constituant la plupart des pièces d'un ordinateur. Il est un peu tordu, mais il fait son boulot. -oc:tooltip.upgradeangel=Permet aux robots pour placer des blocs d'air mince, même s'il n'y a aucun point de référence. -oc:tooltip.upgradebattery=Augmentez la quantité d'énergie qu'un robot peut stocker, le permettant de marcher plus longtemps sans devoir être rechargé. [nl] Capacité : §f%s§7 -oc:tooltip.upgradechunkloader=Si un robot se déplace dans une forêt sans personne à proximité, se déplace-il vraiment ? Cette amélioration s'assure qu'il le fait. Elle garde le chunk du robot chargé, mais consomme continuellement de l'énergie lors qu'il est actif. -oc:tooltip.upgradecontainercard=Cette amélioration de conteneur permet l'installation ou le retrait dynamique d'une carte du robot assemblé. [nl] Niv. Maximum : §f%s§7 -oc:tooltip.upgradecontainerupgrade=Cette amélioration de conteneur permet l'installation ou le retrait dynamique d'une amélioration du robot assemblé. [nl] Niv. Maximum : §f%s§7 -oc:tooltip.upgradecrafting=Permet aux robots d'utiliser le coin en haut à gauche de leur inventaire comme table d'artisanat. Vous devez respecter la position des objets comme pour un artisanat normal. -oc:tooltip.upgradedatabase=Cette amélioration permet de stoquer les information de pile d'éléments pour une utilisation future d'autres composants. Notez que ceci doit être configuré à la main.[nl] Entrées supportées : §f%s§7 -oc:tooltip.upgradeexperience=Cette amélioration permet aux robots d'accumuler de l'experience en exécutant diverses opérations. Plus ils gagnent d'expérience, plus ils peuvent stocker de l'énergie, miner plus rapidement et utiliser les outils plus efficacement. -oc:tooltip.upgradegenerator=Utilisé pour générer de l'énergie directement sur un robot, indépendament d'un chargeur. Consume du comburant (ex: charbon) pour une génération sur la durée, en fonction de l'efficacité du combustible. [nl] §fEfficacité§7: §a%s%%§7 -oc:tooltip.upgradeinventory=Cette amélioration donne un espace d'inventaire au robot. Sans l'une d'elles, les robots ne seraient pas capable de stocker des éléments en interne. -oc:tooltip.upgradeinventorycontroller=Cette amélioration permet au robot plus de contrôle sur ses interactions avec les inventaires externes, et leur permet d'échanger leurs outils avec un élément de son inventaire. -oc:tooltip.upgradenavigation=Utilisé pour déterminer la position et l'orientation d'un robot. Cette position est relative au centre de la zone (affichée sur une carte) ou l'amélioration a été créée. -oc:tooltip.upgradepiston=Cette amélioration est très rentre-dedans. Elle permet de déplacer des blocs comme lors de l'utilisation d'un piston. malgré tout, cela §lne déplace pas§7 les entités. -oc:tooltip.upgradesign=Permets de lire et d'écrire sur des panneaux. -oc:tooltip.upgradesolargenerator=Utilisé pour générer de l'énergie directement sur un robot, indépendament d'un chargeur, via le soleil. Aucun bloc ne doit se trouver au-dessus du robot pour que cette génération fonctionne. Génère de l'énergie à %s%% de la vitesse d'un moteur stirling (BuildCraft). -oc:tooltip.upgradetank=Cette amélioration donne un réservoire de fluides au robot. Sans l'une d'elles, les robots ne seraient pas capable de stocker des fluides en interne. -oc:tooltip.upgradetankcontroller=Cette amélioration permet au robot plus de contrôle sur ses interactions avec les réservoirs externes, et leur permet de transférer les fluides avec un élément réservoir de fluide de son inventaire. -oc:tooltip.upgradetractorbeam=Equipe le robot avec une technologie extrêmement avancée, surnommé "l'aimant d'éléments". Cela lui permet de prendre des éléments n'importe où 3 blocs autour de son emplacement. -oc:tooltip.wirelessnetworkcard=Permet l'envoi de messages réseaux sans fil. Pensez à régler la §fforce du signal§7, sinon aucun paquet ne sera envoyé! - -# NEI Integration -nei.options.inventory.oredict=Montrez les noms OreDictionary -nei.options.inventory.oredict.true=Vrai -nei.options.inventory.oredict.false=Faux - -# Waila Integration -option.oc.address=Adresse -option.oc.componentName=Nom du composant -option.oc.energy=Énergie diff --git a/src/main/resources/assets/opencomputers/lang/fr_fr.json b/src/main/resources/assets/opencomputers/lang/fr_fr.json new file mode 100644 index 0000000000..a9c2966662 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/fr_fr.json @@ -0,0 +1,340 @@ +{ + "tile.oc.accesspoint": "Point d'accès", + "tile.oc.adapter": "Adaptateur", + "tile.oc.assembler": "Assembleur électronique", + "tile.oc.cable": "Câble", + "tile.oc.capacitor": "Capaciteur", + "tile.oc.case1": "Boitier (Niveau 1)", + "tile.oc.case2": "Boitier (Niveau 2)", + "tile.oc.case3": "Boitier (Niveau 3)", + "tile.oc.casecreative": "Boitier (Créatif)", + "tile.oc.chameliumblock": "Bloc de Chamélium", + "tile.oc.charger": "Chargeur", + "tile.oc.disassembler": "Désassembleur", + "tile.oc.diskdrive": "Lecteur de disquettes", + "tile.oc.endstone": "Pierre du néant", + "tile.oc.geolyzer": "Géoliseur", + "tile.oc.hologram1": "Projecteur d'hologramme (Niveau 1)", + "tile.oc.hologram2": "Projecteur d'hologramme (Niveau 2)", + "tile.oc.keyboard": "Clavier", + "tile.oc.microcontroller": "Micro-contrôleur", + "tile.oc.motionsensor": "Détecteur de mouvement", + "tile.oc.netsplitter": "Répartiteur réseau", + "tile.oc.powerconverter": "Convertisseur énergétique", + "tile.oc.powerdistributor": "Distributeur énergétique", + "tile.oc.print": "Impression 3D", + "tile.oc.printer": "Imprimante 3D", + "tile.oc.raid": "Raid", + "tile.oc.redstone": "Redstone E/S", + "tile.oc.relay": "Relai", + "tile.oc.robot": "Robot", + "tile.oc.robotafterimage": "Robot", + "tile.oc.screen1": "Ecran (Niveau 1)", + "tile.oc.screen2": "Ecran (Niveau 2)", + "tile.oc.screen3": "Ecran (Niveau 3)", + "tile.oc.rack": "Support de serveur", + "tile.oc.switch": "Routeur", + "tile.oc.transposer": "Transposeur", + "tile.oc.waypoint": "Point de passage", + "item.oc.abstractbuscard": "Carte de bus abstraite", + "item.oc.acid": "Grog", + "item.oc.alu": "Unité de Logique Arithmétique (ULA)", + "item.oc.analyzer": "Analyseur", + "item.oc.apu0": "Unité de Traitement Accélérée (UTA) (Niveau 1)", + "item.oc.apu1": "Unité de Traitement Accélérée (UTA) (Niveau 2)", + "item.oc.apu2": "Unité de Traitement Accélérée (UTA) (Créatif)", + "item.oc.arrowkeys": "Touches directionnelles", + "item.oc.buttongroup": "Groupe de boutons", + "item.oc.cardbase": "Base de carte", + "item.oc.chamelium": "Chamélium", + "item.oc.circuitboard": "Plaque de circuit imprimé", + "item.oc.componentbus0": "Bus des composants (Niveau 1)", + "item.oc.componentbus1": "Bus des composants (Niveau 2)", + "item.oc.componentbus2": "Bus des composants (Niveau 3)", + "item.oc.controlunit": "Unité de contrôle (UC)", + "item.oc.cpu0": "Processeur (Niveau 1)", + "item.oc.cpu1": "Processeur (Niveau 2)", + "item.oc.cpu2": "Processeur (Niveau 3)", + "item.oc.cuttingwire": "Fil de coupe", + "item.oc.debugcard": "Carte de débogueur", + "item.oc.debugger": "Débogueur réseau", + "item.oc.disk": "Disque", + "item.oc.drone": "Drone", + "item.oc.dronecase0": "Boitier de drone (Niveau 1)", + "item.oc.dronecase1": "Boitier de drone (Niveau 2)", + "item.oc.dronecase3": "Boitier de drone (Créatif)", + "item.oc.eeprom": "EEPROM", + "item.oc.floppydisk": "Disquette", + "item.oc.graphicscard0": "Carte graphique (Niveau 1)", + "item.oc.graphicscard1": "Carte graphique (Niveau 2)", + "item.oc.graphicscard2": "Carte graphique (Niveau 3)", + "item.oc.harddiskdrive0": "Disque dur (Niveau 1)", + "item.oc.harddiskdrive1": "Disque dur (Niveau 2)", + "item.oc.harddiskdrive2": "Disque dur (Niveau 3)", + "item.oc.hoverboots": "Bottes de vol plané", + "item.oc.inkcartridge": "Cartouche d'encre", + "item.oc.inkcartridgeempty": "Cartouche d'encre (Vide)", + "item.oc.internetcard": "Carte internet", + "item.oc.interweb": "Interweb", + "item.oc.ironnugget": "Pépite de fer", + "item.oc.linkedcard": "Carte liée", + "item.oc.manual": "Manuel d'OpenComputers", + "item.oc.memory0": "Mémoire (Niveau 1)", + "item.oc.memory1": "Mémoire (Niveau 1.5)", + "item.oc.memory2": "Mémoire (Niveau 2)", + "item.oc.memory3": "Mémoire (Niveau 2.5)", + "item.oc.memory4": "Mémoire (Niveau 3)", + "item.oc.memory5": "Mémoire (Niveau 3.5)", + "item.oc.microchip0": "Puce électronique (Niveau 1)", + "item.oc.microchip1": "Puce électronique (Niveau 2)", + "item.oc.microchip2": "Puce électronique (Niveau 3)", + "item.oc.microcontrollercase0": "Boitier de microcontrôleur (Niveau 1)", + "item.oc.microcontrollercase1": "Boitier de microcontrôleur (Niveau 2)", + "item.oc.microcontrollercase3": "Boitier de microcontrôleur (Créatif)", + "item.oc.networkcard": "Carte réseau", + "item.oc.numpad": "Pavé numérique", + "item.oc.present": "Un petit quelque chose...", + "item.oc.printedcircuitboard": "Circuit imprimé", + "item.oc.rawcircuitboard": "Plaque de circuit imprimé brute", + "item.oc.redstonecard0": "Carte de Redstone (Niveau 1)", + "item.oc.redstonecard1": "Carte de Redstone (Niveau 2)", + "item.oc.server0": "Serveur (Niveau 1)", + "item.oc.server1": "Serveur (Niveau 2)", + "item.oc.server2": "Serveur (Niveau 3)", + "item.oc.server3": "Serveur (Créatif)", + "item.oc.tablet": "Tablette", + "item.oc.tabletcase": "Boitier de tablette (Niveau 1)", + "item.oc.tabletcase": "Boitier de tablette (Niveau 2)", + "item.oc.tabletcase": "Boitier de tablette (Créatif)", + "item.oc.terminal": "Terminal à distance", + "item.oc.texturepicker": "Ramasseur de texture", + "item.oc.transistor": "Transistor", + "item.oc.upgradeangel": "Amélioration ange", + "item.oc.upgradebattery0": "Amélioration batterie (Niveau 1)", + "item.oc.upgradebattery1": "Amélioration batterie (Niveau 2)", + "item.oc.upgradebattery2": "Amélioration batterie (Niveau 3)", + "item.oc.upgradechunkloader": "Amélioration chargement de chunk", + "item.oc.upgradecontainercard0": "Conteneur de carte (Niveau 1)", + "item.oc.upgradecontainercard1": "Conteneur de carte (Niveau 2)", + "item.oc.upgradecontainercard2": "Conteneur de carte (Niveau 3)", + "item.oc.upgradecontainerupgrade0": "Amélioration de conteneur (Niveau 1)", + "item.oc.upgradecontainerupgrade1": "Amélioration de conteneur (Niveau 2)", + "item.oc.upgradecontainerupgrade2": "Amélioration de conteneur (Niveau 3)", + "item.oc.upgradecrafting": "Amélioration d'artisanat", + "item.oc.upgradedatabase0": "Amélioration de base de données (Niveau 1)", + "item.oc.upgradedatabase1": "Amélioration de base de données (Niveau 2)", + "item.oc.upgradedatabase2": "Amélioration de base de données (Niveau 3)", + "item.oc.upgradeexperience": "Amélioration d'expérience", + "item.oc.upgradegenerator": "Amélioration de générateur", + "item.oc.upgradehover0": "Amélioration de vol plané (Niveau 1)", + "item.oc.upgradehover1": "Amélioration de vol plané (Niveau 2)", + "item.oc.upgradeinventory": "Amélioration d'inventaire", + "item.oc.upgradeinventorycontroller": "Amélioration du contrôleur d'inventaire", + "item.oc.upgradeleash": "Amélioration de laisse", + "item.oc.upgradenavigation": "Amélioration de navigation", + "item.oc.upgradepiston": "Amélioration de piston", + "item.oc.upgradesign": "Amélioration de panneau d'E/S", + "item.oc.upgradesolargenerator": "Amélioration du générateur solaire", + "item.oc.upgradetank": "Amélioration de réservoir", + "item.oc.upgradetankcontroller": "Amélioration du contrôleur de réservoir", + "item.oc.upgradetractorbeam": "Amélioration du rayon tracteur", + "item.oc.wirelessnetworkcard0": "Carte de réseau sans-fils (Niveau 1)", + "item.oc.wirelessnetworkcard1": "Carte de réseau sans-fils (Niveau 2)", + "item.oc.worldsensorcard": "Carte de capteur du monde", + "item.oc.wrench": "Crisseur", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.Drone": "Drone", + "oc:gui.Analyzer.Address": "§6Addresse§f: %s", + "oc:gui.Analyzer.AddressCopied": "Adresse copiée dans le presse-papier.", + "oc:gui.Analyzer.ChargerSpeed": "§6Vitesse de charge§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Nom du composant§f: %s", + "oc:gui.Analyzer.Components": "§6Nombre de composants connectés§f: %s", + "oc:gui.Analyzer.LastError": "§6Dernière erreur§f: %s", + "oc:gui.Analyzer.RobotName": "§6Nom§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Propriétaire§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Expérience§f: %s", + "oc:gui.Analyzer.StoredEnergy": "§6Energie stockée§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Energie totale§f: %s", + "oc:gui.Analyzer.Users": "§6Utilisateurs§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6Force du signal§f: %s", + "oc:gui.Assembler.Collect": "Collectez la sortie", + "oc:gui.Assembler.Complexity": "Complexité: %s/%s", + "oc:gui.Assembler.InsertCase": "Insérez une partie de base", + "oc:gui.Assembler.InsertCPU": "Insérez une UCP", + "oc:gui.Assembler.InsertRAM": "Insérez un peu de mémoire", + "oc:gui.Assembler.Progress": "Progression: %s%% (%s)", + "oc:gui.Assembler.Run": "Assemble", + "oc:gui.Assembler.Warning.BIOS": "BIOS", + "oc:gui.Assembler.Warning.GraphicsCard": "Carte graphique", + "oc:gui.Assembler.Warning.Inventory": "Amélioration d'inventaire", + "oc:gui.Assembler.Warning.Keyboard": "Clavier", + "oc:gui.Assembler.Warning.OS": "Moyen de démarrage", + "oc:gui.Assembler.Warning.Screen": "Ecran", + "oc:gui.Assembler.Warnings": "§eALERTE§7: Les composants recommandés sont manquant.", + "oc:gui.Chat.NewVersion": "une nouvelle version est disponible: %s", + "oc:gui.Chat.TextureName": "§7Le nom de la texture est §a%s§f.", + "oc:gui.Chat.WarningClassTransformer": "Il y a §cerrors§f lancement dans le transformeur de classe. Veuillez vérifier ceci, en même temps que votre fichier log (plein) FML §alatest.log§f/§afml-server-latest.log§f, Merci !", + "oc:gui.Chat.WarningFingerprint": "§cALERTE§f - Disparité d'empreinte digitale! Attendu '§a%s§f' mais eu '§e%s§f'. À moins que vous ne soyez un modder et que vous exécutiez la version deobfuscated du mod, Il est §lfortement§f recommendé de re-télécharger OpenComputers, parce que le JAR que vous utilisez peut avoir été falsifié.", + "oc:gui.Chat.WarningLink": "Impossible d'ouvrir le lien : %s", + "oc:gui.Chat.WarningLuaFallback": "Les bibliothèques natives Lua ne sont pas disponibles, les ordinateurs ne pourront pas persister en leur état. Ils réamorceront sur la recharge des chunks.", + "oc:gui.Chat.WarningProjectRed": "Vous utilisez une version de Project: Red qui est incompatible avec OpenComputers. Essayez de mettre à jour votre version de Project: Red.", + "oc:gui.Chat.WarningRecipes": "il y a des erreurs au lancement de recettes. Certains éléments doivent être infabricables. Veuillez vérifier votre fichier log pour plus d'information.", + "oc:gui.Error.ComponentOverflow": "Beaucoup trop de composants connectés à l'ordinateur.", + "oc:gui.Error.InternalError": "Erreur interne, Veuillez lire le fichier log. Ceci est probablement une erreur.", + "oc:gui.Error.NoCPU": "Pas d'UCP installé dans cet ordinateur.", + "oc:gui.Error.NoEnergy": "Pas assez d'énergie.", + "oc:gui.Error.NoRAM": "pas de mémoire installée dans cet ordinateur.", + "oc:gui.Error.OutOfMemory": "Mémoire saturée.", + "oc:gui.Manual.Blocks": "Blocs d'OpenComputers", + "oc:gui.Manual.Home": "Accueil", + "oc:gui.Manual.Items": "Éléments d'OpenComputers", + "oc:gui.Manual.Warning.BlockMissing": "Bloc manquant.", + "oc:gui.Manual.Warning.ImageMissing": "Image manquante.", + "oc:gui.Manual.Warning.ItemMissing": "Élément manquant.", + "oc:gui.Manual.Warning.OreDictMissing": "Entrée au dictionnaire de minerai manquante.", + "oc:gui.Raid.Warning": "§4L'ajout d'un disque le nettoie.\nL'enlèvement d'un disque nettoie le raid.", + "oc:gui.Robot.Power": "Énergie", + "oc:gui.Robot.TurnOff": "Éteindre", + "oc:gui.Robot.TurnOn": "Allumer", + "oc:gui.Rack.None": "Aucun", + "oc:gui.Rack.Back": "Arrière", + "oc:gui.Rack.Bottom": "Bas", + "oc:gui.Rack.Left": "Gauche", + "oc:gui.Rack.Right": "Droite", + "oc:gui.Rack.Top": "Haut", + "oc:gui.Switch.TransferRate": "Vitesse du cycle", + "oc:gui.Switch.PacketsPerCycle": "paquets / cycle", + "oc:gui.Switch.QueueSize": "Taille de la file", + "oc:gui.Terminal.InvalidKey": "Clef invalide, très probablement qu'un autre terminal a dû nécessité le serveur.", + "oc:gui.Terminal.OutOfRange": "Pas de signal.", + "oc:container.accesspoint": "Point d'accès", + "oc:container.adapter": "Adapteur", + "oc:container.case": "Ordinateur", + "oc:container.charger": "Chargeur", + "oc:container.disassembler": "Désassembleur", + "oc:container.diskdrive": "Lecteur disque", + "oc:container.printer": "Imprimante", + "oc:container.raid": "Raid", + "oc:container.server": "Serveur", + "oc:container.rack": "Support de serveur", + "oc:container.switch": "Routeur", + "oc:container.tabletwrapper": "Tablette", + "key.opencomputers.analyzeCopyAddress": "Copier l'adresse (Analyseur)", + "key.opencomputers.clipboardPaste": "Coller le presse-papier", + "key.opencomputers.extendedTooltip": "Afficher plus d'informations", + "oc:tooltip.accesspoint": "Fonctionne comme un routeur, de plus il recois les paquets sans-fil et il transmet les paquets filaires au réseau sans-fil.", + "oc:tooltip.abstractbuscard": "Il permet d'interagir avec le bus abstait de §fStargateTech 2§7 lors de l'envoi et de la reception de paquets LIP.", + "oc:tooltip.acid": "Un produit semi-liquide très toxique, uniquement bu par certains pirates. Grâce à ses propriétés corrosives, il est très utile à la gravure de circuits imprimés.", + "oc:tooltip.adapter": "Utilisé pour contrôler des blocs n'étant pas des composants d'ordinateurs, comme des blocs Vanilla ou d'autres mods.", + "oc:tooltip.alu": "Ajoute des nombres pour que vous n'ayez pas à le faire. C'est peut-être mieux comme ça.", + "oc:tooltip.analyzer": "Utilisé pour afficher des informations sur des blocs, comme leur §faddresse§7 et leur §fnom de composant§7.\nAffiche aussi les erreurs en cas de crash d'un ordinateur.", + "oc:tooltip.apu": "Ceci est une UTC avec une UTG intégrée (ou UTI), lorsque vous avez juste besoin d'un emplacement de carte supplémentaire.\nComposants supportés : §f%s§7\nRésolution maximum: §f%sx%s§7\nprofondeur de couleur maxi: §f%s§7\nOpérations/tic: §f%s§7", + "oc:tooltip.assembler": "Il permet de construire des robots et d'autres dispositifs d'un certain nombre de pièces informatiques différentes.", + "oc:tooltip.cable": "Un moyen peu coûteux pour relier les ordinateurs entre eux.", + "oc:tooltip.capacitor": "Stocke l'énergie pour une utilisation ultérieure. Peut être chargé et déchargé très rapidement.", + "oc:tooltip.cardbase": "Comme son nom l'indique, c'est le bloc de construction basique pour toutes les cartes.", + "oc:tooltip.case": "La tour est le bloc principal de l'ordinateur, et héberge ses §fcartes§7, sa §fMémoire RAM§7 et ses §fdisques durs§7.\nEmplacements: §f%s§7", + "oc:tooltip.chamelium": "Matière première pour impression 3D. Ne pas avaler : Peut mener à la cécité et au manque de présence provisoire.", + "oc:tooltip.chameliumblock": "Joli et propre. Pratique pour formes teintées dans les impressions 3D, ou juste pour avoir un bloc propre, coloré, pour décorer votre base fantaisiste avec.", + "oc:tooltip.charger": "Transfère l'énergie depuis des capaciteurs pour les robots adjacents. La puissance du transfert dépends du §fsignal de redstone§7, ou une absence de signal ne charge pas les robots, et un signal maximum charge les robots le plus vite possible.", + "oc:tooltip.circuitboard": "Hé ben, on y arrive. Peut être gravé pour obtenir un circuit imprimé.", + "oc:tooltip.controlunit": "C'est une unité qui... controle... des trucs. On en a besoin pour faire un processeur. Donc, ouais, super important.", + "oc:tooltip.componentbus": "Cette extention autorise aux serveurs de communiquer avec plus composants en même temps, Semblable à ce que les UCP font.\nComposants supportés : §f%s§7", + "oc:tooltip.cpu": "Un composant essentiel pour tout ordinateur. La fréquence d'horloge est un peu douteuse, mais, vous vous attendiez à quoi avec un cadran solaire de poche ?", + "oc:tooltip.cpu.Architecture": "Architecture: §f%s§7", + "oc:tooltip.cuttingwire": "Utilisé pour couper des blocs d'argile en plaque de circuit imprimé. Se casse après utilisation, ce qui rends cet outil le moins efficace jamais utilisé.", + "oc:tooltip.debugcard": "Element en mode créatif, il autorise la manipulation du monde pour faciliter les tests. Utilisation à votre propre péril.", + "oc:tooltip.debugger": "Peut être utilisé pour sortir les information de débogue sur la grille réseau interne de OC. A utiliser seulement si instruit par un dev.", + "oc:tooltip.disassembler": "Sépare les éléments dans leur composants d'origine. §lAttention§7: les éléments ainsi récupérés ont %s%% de chance de ce briser dans le processus !", + "oc:tooltip.disk": "Moyen primitif qui peut être utilisé pour faire des appareils de stockage persistants.", + "oc:tooltip.diskdrive.CC": "Les disquettes ComputerCraft sont §asupportées§7.", + "oc:tooltip.diskdrive": "Permet de lire et d'écrire des disquettes. Peut être installé dans les robots pour permettre d'insérer des disquettes plus tard.", + "oc:tooltip.drone": "Les drones sont de légère unité de reconnaissance rapide avec un espace de chargement limité.", + "oc:tooltip.dronecase": "Ce boitier est utilisé pour construire des Drones dans l'assembleur. Il a des emplacement pour une petite quantité de composant et fournit la lévitation en pierre de néant alimentée.", + "oc:tooltip.eeprom": "Petit, stockage programmable qui contient le BIOS que les ordinateurs utilisent pour démarrer.", + "oc:tooltip.fakeendstone": "Presque aussi bon que la chose réelle, imite même sa flottabilité !", + "oc:tooltip.geolyzer": "Permet de scanner la dureté des blocs des environs. Ces informations peuvent être utiles pour produire un hologramme de la zone ou pour détecter les minerais.", + "oc:tooltip.graphicscard": "Utilisé pour changer ce qui est affiché sur écran.\nRésolution maximum: §f%sx%s§7\nCouleurs maximales: §f%s§7\nOperations/tick: §f%s§7", + "oc:tooltip.hoverboots": "Sautez plus haut, tombez plus bas, marchez mieux. Ceci et plus, avec les nouvelles Bottes de vol plané (TM).", + "oc:tooltip.inkcartridge": "Utilisé pour remplir d'encre les imprimantes 3D. Pour des raisons mystérieuses, elle ne doit pas rester dans l'imprimante.", + "oc:tooltip.inkcartridgeempty": "Cette cartouche d'encre a été vidé totalement. Remplissez la avec des couleurs. Ou jetez la. Voyez comme je m'en soucie.", + "oc:tooltip.internetcard": "Cette carte permet de faire des requêtes HTTP et utiliser de véritable TCP sockets.", + "oc:tooltip.interweb": "Félicitation, vous avez gagné un (1) interweb. Vous pouvez y connecter en utilisant une carte internet. Prenez garde : n'alimentez pas les trolls.", + "oc:tooltip.ironnugget": "Une pépite de fer. D'où son nom.", + "oc:tooltip.keyboard": "Peut être attaché à un écran pour permettre la saisie.", + "oc:tooltip.hologram0": "Un affichage volumétrique qui peut être contrôlé par des ordinateurs pour montrer des structures de voxel arbitraires.\nRésolution : §f48x32x48§7\nEchelle maxi : §f3x§7\nColorimétrie : §fMonochrome§7", + "oc:tooltip.hologram1": "Un affichage volumétrique qui peut être contrôlé par des ordinateurs pour montrer des structures de voxel arbitraires.\nRésolution : §f48x32x48§7\nEchelle maxi : §f4x§7\nColorimétrie : §fTricolore§7", + "oc:tooltip.linkedcard": "Elles sont fabriqué par paire et ne peuvent communiquer qu'avec leur Carte partenaire. Cependant, elles peuvent communiquer à travers n'importe quelle distance et même à travers les dimensions. L'énergie exigée pour envoyer un message est assez haute malgès tout.", + "oc:tooltip.linkedcard_channel": "§8Canal : %s§7", + "oc:tooltip.manual": "Toutes les informations vous pourriez probablement avoir besoin sur OpenComputers. Et plus. Au prix incroyablement bas de... §oveuillez appuyer sur R pour continuer§7.", + "oc:tooltip.materialcosts": "Prend [§f%s§7] pour les coûts des matériaux.", + "oc:tooltip.materials": "Materiaux :", + "oc:tooltip.memory": "Requis pour faire fonctionner les ordinateurs. Plus vous en avez, plus complexes les programmes seront utilisables.", + "oc:tooltip.microchip": "La puce anciennement circuit intégré. J'ai aucune idée du comment ça marche avec la redstone, mais ça marche.", + "oc:tooltip.microcontroller": "Les microcontrôleurs sont des ordinateurs résumés à l'essentiel. Ils sont destinés pour s'occuper de tâches très spécifiques, dirigant seulement l'unique programme que lui donne l'EEPROM qu'il intègre.", + "oc:tooltip.microcontrollercase": "Composant de base pour construire des microcontrôleurs. Placez-le dans un assembleur pour ajouter de nouveaux composants et assemblez un microcontrôleur.", + "oc:tooltip.motionsensor": "Peut détecter le mouvement d'êtres vivants à proximité. Demande une ligne de vue dégagée.", + "oc:tooltip.networkcard": "Permet à des ordinateurs distants de communiquer en s'envoyant des messages.", + "oc:tooltip.poweracceptor": "Vitesse de convertion d'énergie: §f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§fBuildCraft en MJ§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§fCharges de Factorization§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fIndustrialCraft² en EU§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§fMekanism en Joules§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fThermal Expansion en RF§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fResonant Engine en Coulombs§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Convertis l'énergie d'autres mods en l'énergie requise pour faire fonctionner les ordinateurs.", + "oc:tooltip.powerdistributor": "Distribue l'énergie dans plusieurs réseaux. Utile pour partager cette énergie depuis un convertisseur vers différents sous-réseaux qui doivent rester séparés.", + "oc:tooltip.present": "... pour vos ennuis. Ouvrez ce cadeau pour une chance de recevoir quelques éléments d'OpenCompucters §kpsorti du chapeaut§7!\n§8 quand c'est le bon momment de recevoir un cadeau.§7", + "oc:tooltip.print.BeaconBase": "§8Fonctionne comme une base de balise.", + "oc:tooltip.print.LightValue": "§8Lumière émise : %s.", + "oc:tooltip.print.RedstoneLevel": "§8Sortie Redstone : %s.", + "oc:tooltip.printedcircuitboard": "Le composant basique pour les cartes, la mémoire, etc.", + "oc:tooltip.raid": "Permet de combiner trois disques durs dans un plus grand système de fichiers qui pourra être utilisé par tous les ordinateurs connectés.", + "oc:tooltip.rawcircuitboard": "Peut être durci dans n'importe quel four.", + "oc:tooltip.redstone": "Permet de recevoir et d'émettre des signaux de redstone autour du bloc. Contrôlable par n'importe quel ordinateur connecté à ce bloc. En gros, une carte redstone externe.", + "oc:tooltip.redstonecard.ProjectRed": "§fProjectRed§7 est §asupporté7.", + "oc:tooltip.redstonecard.RedLogic": "§fRedLogic§7 est §asupporté§7.", + "oc:tooltip.redstonecard.RedNet": "§fRedNet§7 est §asupporté§7.", + "oc:tooltip.redstonecard.WirelessCBE": "§fWireless Redstone (ChickenBones)§7 est §asupporté§7.", + "oc:tooltip.redstonecard.WirelessSV": "§fWireless Redstone (SlimeVoid)§7 est §asupporté§7.", + "oc:tooltip.redstonecard": "Permet la réception et l'émission de signaux de redstone autour de l'ordinateur ou du robot.", + "oc:tooltip.robot": "Contrairement aux ordinateurs, les robots peuvent se déplacer et intéragir avec le monde comme un joueur le fait. Ils ne peuvent §opas§r§7 intéragir avec des composants d'ordinateur extérieurs, ceci dit !", + "oc:tooltip.robot_level": "§fNiveau§7: §a%s§7.", + "oc:tooltip.robot_storedenergy": "§fEnergie stockée§7: §a%s§7.", + "oc:tooltip.screen": "Affiche du texte, contrôlé par une Carte graphique dans un Boitier.\nRésolution maximum: §f%sx%s§7\nCouleurs maximales: §f%s§7", + "oc:tooltip.server": "Ceci est un serveur, il y en a beaucoup comme ca, mais celui-ci peut être amélioré avec des composants bien plus qu'un ordinateur peut l'être. Il peut être placé dans un support de serveur.", + "oc:tooltip.server.Components": "Composants installés :", + "oc:tooltip.rack": "Permet l'installation jusqu'à quatre serveurs.", + "oc:tooltip.switch": "Permet de connecter différents réseaux entre eux. Seulement des messages réseau seront transmis, les composants ne seront pas visibles via celui ci. A utiliser pour séparer des réseaux tout en leur permettant de communiquer entre eux, grâce aux Cartes réseau, par exemple.", + "oc:tooltip.tablet": "Une tablette, pour une Lua fraiche en route. Peut être forcé à l'arrêt par un accroupi-clique droit.", + "oc:tooltip.tabletcase": "Boitier de tablettes de base. Placez-le dans l'assembleur pour ajouter des composants et créez une tablette.", + "oc:tooltip.terminal": "Permet de contrôler un serveur à distance, tant que vous êtes à portée de lui. Fonctionne comme un écran-clavier portable. Maj-clique droit un serveur du support pour le lier au terminal.", + "oc:tooltip.tier": "§8Niv. %s", + "oc:tooltip.toolong": "Maintenez la touche [§f%s§7] pour plus d'informations.", + "oc:tooltip.transistor": "Un élément basique constituant la plupart des pièces d'un ordinateur. Il est un peu tordu, mais il fait son boulot.", + "oc:tooltip.upgradeangel": "Permet aux robots pour placer des blocs d'air mince, même s'il n'y a aucun point de référence.", + "oc:tooltip.upgradebattery": "Augmentez la quantité d'énergie qu'un robot peut stocker, le permettant de marcher plus longtemps sans devoir être rechargé.\nCapacité : §f%s§7", + "oc:tooltip.upgradechunkloader": "Si un robot se déplace dans une forêt sans personne à proximité, se déplace-il vraiment ? Cette amélioration s'assure qu'il le fait. Elle garde le chunk du robot chargé, mais consomme continuellement de l'énergie lors qu'il est actif.", + "oc:tooltip.upgradecontainercard": "Cette amélioration de conteneur permet l'installation ou le retrait dynamique d'une carte du robot assemblé.\nNiv. Maximum : §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "Cette amélioration de conteneur permet l'installation ou le retrait dynamique d'une amélioration du robot assemblé.\nNiv. Maximum : §f%s§7", + "oc:tooltip.upgradecrafting": "Permet aux robots d'utiliser le coin en haut à gauche de leur inventaire comme table d'artisanat. Vous devez respecter la position des objets comme pour un artisanat normal.", + "oc:tooltip.upgradedatabase": "Cette amélioration permet de stoquer les information de pile d'éléments pour une utilisation future d'autres composants. Notez que ceci doit être configuré à la main.\nEntrées supportées : §f%s§7", + "oc:tooltip.upgradeexperience": "Cette amélioration permet aux robots d'accumuler de l'experience en exécutant diverses opérations. Plus ils gagnent d'expérience, plus ils peuvent stocker de l'énergie, miner plus rapidement et utiliser les outils plus efficacement.", + "oc:tooltip.upgradegenerator": "Utilisé pour générer de l'énergie directement sur un robot, indépendament d'un chargeur. Consume du comburant (ex: charbon) pour une génération sur la durée, en fonction de l'efficacité du combustible.\n§fEfficacité§7: §a%s%%§7", + "oc:tooltip.upgradeinventory": "Cette amélioration donne un espace d'inventaire au robot. Sans l'une d'elles, les robots ne seraient pas capable de stocker des éléments en interne.", + "oc:tooltip.upgradeinventorycontroller": "Cette amélioration permet au robot plus de contrôle sur ses interactions avec les inventaires externes, et leur permet d'échanger leurs outils avec un élément de son inventaire.", + "oc:tooltip.upgradenavigation": "Utilisé pour déterminer la position et l'orientation d'un robot. Cette position est relative au centre de la zone (affichée sur une carte) ou l'amélioration a été créée.", + "oc:tooltip.upgradepiston": "Cette amélioration est très rentre-dedans. Elle permet de déplacer des blocs comme lors de l'utilisation d'un piston. malgré tout, cela §lne déplace pas§7 les entités.", + "oc:tooltip.upgradesign": "Permets de lire et d'écrire sur des panneaux.", + "oc:tooltip.upgradesolargenerator": "Utilisé pour générer de l'énergie directement sur un robot, indépendament d'un chargeur, via le soleil. Aucun bloc ne doit se trouver au-dessus du robot pour que cette génération fonctionne. Génère de l'énergie à %s%% de la vitesse d'un moteur stirling (BuildCraft).", + "oc:tooltip.upgradetank": "Cette amélioration donne un réservoire de fluides au robot. Sans l'une d'elles, les robots ne seraient pas capable de stocker des fluides en interne.", + "oc:tooltip.upgradetankcontroller": "Cette amélioration permet au robot plus de contrôle sur ses interactions avec les réservoirs externes, et leur permet de transférer les fluides avec un élément réservoir de fluide de son inventaire.", + "oc:tooltip.upgradetractorbeam": "Equipe le robot avec une technologie extrêmement avancée, surnommé \"l'aimant d'éléments\". Cela lui permet de prendre des éléments n'importe où 3 blocs autour de son emplacement.", + "oc:tooltip.wirelessnetworkcard": "Permet l'envoi de messages réseaux sans fil. Pensez à régler la §fforce du signal§7, sinon aucun paquet ne sera envoyé!", + "nei.options.inventory.oredict": "Montrez les noms OreDictionary", + "nei.options.inventory.oredict.true": "Vrai", + "nei.options.inventory.oredict.false": "Faux", + "option.oc.address": "Adresse", + "option.oc.componentName": "Nom du composant", + "option.oc.energy": "Énergie" +} diff --git a/src/main/resources/assets/opencomputers/lang/it_IT.lang b/src/main/resources/assets/opencomputers/lang/it_IT.lang deleted file mode 100644 index 11dfb3ec67..0000000000 --- a/src/main/resources/assets/opencomputers/lang/it_IT.lang +++ /dev/null @@ -1,271 +0,0 @@ -# Use [nl] to for a line break. - -# Blocks -tile.oc.accesspoint.name=Punto di Accesso -tile.oc.adapter.name=Adattatore -tile.oc.assembler.name=Assemblatore Elettronico -tile.oc.cable.name=Cavo -tile.oc.capacitor.name=Condendatore -tile.oc.case1.name=Computer Case (Livello 1) -tile.oc.case2.name=Computer Case (Livello 2) -tile.oc.case3.name=Computer Case (Livello 3) -tile.oc.casecreative.name=Computer Case (Creativo) -tile.oc.charger.name=Caricabatterie -tile.oc.disassembler.name=Disassemblatore -tile.oc.diskdrive.name=Unità Disco -tile.oc.geolyzer.name=Geolyzer -tile.oc.keyboard.name=Tastiera -tile.oc.hologram1.name=Proiettore Ologrammi (Livello 1) -tile.oc.hologram2.name=Proiettore Ologrammi (Livello 2) -tile.oc.motionsensor.name=Sensore di Movimento -tile.oc.powerconverter.name=Convertitore di Energia -tile.oc.powerdistributor.name=Distributore di Energia -tile.oc.redstone.name=Pietrarossa I/O -tile.oc.robot.name=Robot -tile.oc.robotafterimage.name=Robot -tile.oc.screen1.name=Schermo (Livello 1) -tile.oc.screen2.name=Schermo (Livello 2) -tile.oc.screen3.name=Schermo (Livello 3) -tile.oc.rack.name=Rack -tile.oc.switch.name=Switch - -# Items -item.oc.abstractbuscard.name=Scheda Bus Astratto -item.oc.acid.name=Grog -item.oc.alu.name=Unità Aritmetica Logica (ALU) -item.oc.analyzer.name=Analizzatore -item.oc.arrowkeys.name=Tasti Freccia -item.oc.buttongroup.name=Gruppo di Pulsanti -item.oc.cardbase.name=Scheda Base -item.oc.circuitboard.name=Circuito -item.oc.controlunit.name=Unità di Controllo (CU) -item.oc.componentbus0.name=Bus Periferiche (Livello 1) -item.oc.componentbus1.name=Bus Periferiche (Livello 2) -item.oc.componentbus2.name=Bus Periferiche (Livello 3) -item.oc.cpu0.name=Unità di Elaborazione Centrale (CPU) (Livello 1) -item.oc.cpu1.name=Unità di Elaborazione Centrale (CPU) (Livello 2) -item.oc.cpu2.name=Unità di Elaborazione Centrale (CPU) (Livello 3) -item.oc.cuttingwire.name=Taglierina -item.oc.debugcard.name=Scheda di Debug -item.oc.disk.name=Disco -item.oc.floppydisk.name=Disco Floppy -item.oc.graphicscard0.name=Scheda Grafica (Livello 1) -item.oc.graphicscard1.name=Scheda Grafica (Livello 2) -item.oc.graphicscard2.name=Scheda Grafica (Livello 3) -item.oc.harddiskdrive0.name=Disco Rigido (Livello 1) -item.oc.harddiskdrive1.name=Disco Rigido (Livello 2) -item.oc.harddiskdrive2.name=Disco Rigido (Livello 3) -item.oc.internetcard.name=Scheda Internet -item.oc.interweb.name=Interweb -item.oc.ironnugget.name=Pepita di Ferro -item.oc.linkedcard.name=Scheda Collegata -item.oc.memory0.name=Memoria (Livello 1) -item.oc.memory1.name=Memoria (Livello 1.5) -item.oc.memory2.name=Memoria (Livello 2) -item.oc.memory3.name=Memoria (Livello 2.5) -item.oc.memory4.name=Memoria (Livello 3) -item.oc.memory5.name=Memoria (Livello 3.5) -item.oc.microchip0.name=Microchip (Livello 1) -item.oc.microchip1.name=Microchip (Livello 2) -item.oc.microchip2.name=Microchip (Livello 3) -item.oc.networkcard.name=Scheda di Rete -item.oc.numpad.name=Tastierino Numerico -item.oc.printedcircuitboard.name=Circuito Stampato (PCB) -item.oc.rawcircuitboard.name=Circuito Grezzo -item.oc.redstonecard0.name=Scheda Pietrarossa (Livello 1) -item.oc.redstonecard1.name=Scheda Pietrarossa (Livello 2) -item.oc.server0.name=Server (Livello 1) -item.oc.server1.name=Server (Livello 2) -item.oc.server2.name=Server (Livello 3) -item.oc.server3.name=Server (Creativo) -item.oc.tablet.name=Tablet -item.oc.tabletcase0.name=Custodia Tablet (Livello 1) -item.oc.tabletcase1.name=Custodia Tablet (Livello 2) -item.oc.tabletcase3.name=Custodia Tablet (Creativo) -item.oc.terminal.name=Terminale Remoto -item.oc.transistor.name=Transistor -item.oc.upgradeangel.name=Upgrade Angel -item.oc.upgradebattery0.name=Upgrade Batteria (Livello 1) -item.oc.upgradebattery1.name=Upgrade Batteria (Livello 2) -item.oc.upgradebattery2.name=Upgrade Batteria (Livello 3) -item.oc.upgradechunkloader.name=Upgrade Chunkloader -item.oc.upgradecontainercard0.name=Contenitore Schede (Livello 1) -item.oc.upgradecontainercard1.name=Contenitore Schede (Livello 2) -item.oc.upgradecontainercard2.name=Contenitore Schede (Livello 3) -item.oc.upgradecontainerupgrade0.name=Upgrade Contenitore (Livello 1) -item.oc.upgradecontainerupgrade1.name=Upgrade Contenitore (Livello 2) -item.oc.upgradecontainerupgrade2.name=Upgrade Contenitore (Livello 3) -item.oc.upgradecrafting.name=Upgrade Crafting -item.oc.upgradeexperience.name=Upgrade Esperienza -item.oc.upgradegenerator.name=Upgrade Generatore -item.oc.upgradeinventory.name=Upgrade Inventario -item.oc.upgradeinventorycontroller.name=Upgrade Controllore Inventario -item.oc.upgradenavigation.name=Upgrade Navigazione -item.oc.upgradepiston.name=Upgrade Pistoni -item.oc.upgradesign.name=Upgrade I/O Cartelli -item.oc.upgradesolargenerator.name=Upgrade Panneli Solari -item.oc.upgradetank.name=Upgrade Taniche -item.oc.upgradetankcontroller.name=Upgrade Controllore Taniche -item.oc.upgradetractorbeam.name=Upgrade Raggio Traente -item.oc.wirelessnetworkcard0.name=Scheda di Rete Wireless (Livello 1) -item.oc.wirelessnetworkcard1.name=Scheda di Rete Wireless (Livello 2) - -# GUI -oc:gui.Analyzer.Address=§6Indirizzo§f: %s -oc:gui.Analyzer.AddressCopied=Indirizzo copiato negli appunti. -oc:gui.Analyzer.ChargerSpeed=§6Velocità ricarica§f: %s -oc:gui.Analyzer.ComponentName=§6Nome componente§f: %s -oc:gui.Analyzer.Components=§6Numero componenti connessi§f: %s -oc:gui.Analyzer.LastError=§6Ultimo errore§f: %s -oc:gui.Analyzer.RobotName=§6Nome§f: %s -oc:gui.Analyzer.RobotOwner=§6Proprietario§f: %s -oc:gui.Analyzer.RobotXp=§6Esperienza§f: %s (Livelli %s) -oc:gui.Analyzer.StoredEnergy=§6Energia immagazzinata§f: %s -oc:gui.Analyzer.TotalEnergy=§6Totale energia immagazzinata§f: %s -oc:gui.Analyzer.Users=§6Utenti§f: %s -oc:gui.Analyzer.WirelessStrength=§6Potenza segnale§f: %s -oc:gui.Assembler.Collect=Collect output -oc:gui.Assembler.Complexity=Complessità: %s/%s -oc:gui.Assembler.InsertCase=Inserisci un case -oc:gui.Assembler.InsertCPU=Inserisci una CPU -oc:gui.Assembler.InsertRAM=Inserisci della RAM -oc:gui.Assembler.Progress=Progresso: %s%% (%s) -oc:gui.Assembler.Run=Assembla -oc:gui.Assembler.Warnings=§eAttenzione§7: Mancano i componenti raccomandati. -oc:gui.Assembler.Warning.GraphicsCard=Scheda Grafica -oc:gui.Assembler.Warning.Inventory=Upgrade Inventario -oc:gui.Assembler.Warning.Keyboard=Tastiera -oc:gui.Assembler.Warning.OS=Disco di Boot -oc:gui.Assembler.Warning.Screen=Schermo -oc:gui.Chat.NewVersion=Una nuova versione è disponibile: %s -oc:gui.Chat.WarningFingerprint=§cATTENZIONE§f - mancata corrispondenza dei fingerprint! Atteso '§a%s§f' ma ottenuto '§e%s§f'. Tranne nel caso tu sia un mod che stai utilizzando una versione decomppilata, è §lfortemente§f raccomantado riscaricare OpenComputers, perché il file JAR che stai utilizzando potrebbe essere stato corrotto. -oc:gui.Chat.WarningLuaFallback=Le librerie Lua Native non sono disponibili, i computers non saranno in gredo di mantenere il loro stato di persostenza. Essi verranno riavviati quando il chunk viene ricaricato. -oc:gui.Chat.WarningProjectRed=Stai utilizzando una versione di Project: Red che è incompatibile con OpenComputers. Prova ad aggriornare la tua versione di Project: Red. -oc:gui.Error.ComponentOverflow=Troppi componenti connessi al computer. -oc:gui.Error.InternalError=Errore interno, per favore vedi il file di log. Questo è probabilmente un bug. -oc:gui.Error.NoCPU=Nessuna CPU instllata nel computer. -oc:gui.Error.NoEnergy=Energia insufficiente. -oc:gui.Error.NoRAM=Nessuna RAM installata nel computer. -oc:gui.Error.OutOfMemory=Memoria esaurita. -oc:gui.Robot.Power=Energia -oc:gui.Robot.TurnOff=Spegni -oc:gui.Robot.TurnOn=Accendi -oc:gui.Rack.None=Nessuno -oc:gui.Rack.Back=Indietro -oc:gui.Rack.Bottom=Basso -oc:gui.Rack.Left=Sinistra -oc:gui.Rack.Right=Destra -oc:gui.Rack.Top=Alto -oc:gui.Switch.TransferRate=Tasso di ciclo -oc:gui.Switch.PacketsPerCycle=Pacchetti / ciclo -oc:gui.Switch.QueueSize=Dimensione coda -oc:gui.Terminal.InvalidKey=Tasto invalido, molto probabilmente un altro terminale è stato collegato al server. -oc:gui.Terminal.OutOfRange=Nessun segnale - -# Containers -oc:container.accesspoint=Punto di accesso -oc:container.adapter=Adattatore -oc:container.charger=Caricabatterie -oc:container.case=Computer -oc:container.disassembler=Disassemblatore -oc:container.diskdrive=Unità Disco -oc:container.server=Server -oc:container.rack=Rack -oc:container.switch=Switch -oc:container.tabletwrapper=Tablet - -# Keybinds -key.materialCosts=Mostra Costi Materiali -key.clipboardPaste=Copia negli Appunti - -# Item / Block Tooltips -oc:tooltip.accesspoint=Funziona come uno Switch, ma può anche ricevere pacchetti wireless ed inoltrare pacchetti ricevuti via cavo in modo wireless. -oc:tooltip.abstractbuscard=Consente di interagire con il bus astratto di §fStargateTech 2§7 inviando e ricevendo pacchetti LIP. -oc:tooltip.acid=Un liquido altamente tossico, normalmente consumato solo da alcuni pirati. Grazie alla sua natura corrosiva è particolarmente adatto per l'incisione dei circuiti stampati. -oc:tooltip.adapter=Utilizzato per controllare blocchi che non sono componenti, come blocchi vanilla di minecraft e blocchi di altri mod. -oc:tooltip.alu=Calcola le somme così non devi farlo tu. Potrebbe essere meglgio così. -oc:tooltip.analyzer=Utilizzato per mostrare informazioni riguardo i blocchi, come il loro §findirizzo§7 e il loro §fnome del componente§7.[nl] Inoltre mostra gli errori che hanno causato un crash del computer, se non è stato spento normalmente. -oc:tooltip.assembler=Permette di costruire robot e altri dispositivi da un certo numero di parti di computer. -oc:tooltip.cable=Un modo economico per connettere i blocchi. -oc:tooltip.capacitor=Immagazzina energia per un uso successivo. Può essere riempito e svuotato molto rapidamente. -oc:tooltip.cardbase=Come indica il nome, questo è l'elemento di base per tutte le schede di espansione. -oc:tooltip.case=Il case del computer è l'elemento di base per i computer e ospita le §fschede di espansione§7, la §fRAM§7 e il §fdisco rigido§7.[nl] Slots: §f%s§7 -oc:tooltip.charger=Trasferisce energia nei robot adiacenti. La velocità di trasferimento dipende dal §fsegnale di pietrarossa§7 applicato, dove nessun segnale significa di non ricaricare i robot e segnale massimo significa ricarica alla massima velocità. -oc:tooltip.circuitboard=Ora stiamo ottenendo qualcosa. Può essere inciso per ottenere un circuito stampato. -oc:tooltip.controlunit=Questa è l'unità che ... controlla ... cose. È necessario per costruire una CPU. Quindi sì, è assolutamente importante. -oc:tooltip.componentbus=Questa espansione consente ai server di comunicare con più componenti, allo stesso tempo, in modo simile a come fanno le CPU.[nl] Componenti supportati: §f%s§7 -oc:tooltip.cpu=Una componente essenziale di tutti i computer. La frequenza di clock è un po' inaffidabile, ma cosa vi aspettate quando viene eseguito da una meridiana tascabile?[nl] Componenti supportati: §f%s§7 -oc:tooltip.cpu.Architecture=Architettura: §f%s§7 -oc:tooltip.cuttingwire=Usato per tagliare i blocchi di argilla in circuiti. Si rompe dopo l'uso, che rende probabilmente lo rende strumento più inefficiente mai visto. -oc:tooltip.debugcard=Oggetto per la modalità creativa, permette manipolare il mondo per rendere il testing più facile. Utilizzare a proprio rischio e pericolo. -oc:tooltip.disassembler=Separa gli oggetti nelle loro componenti originali. §lAttenzione§7: gli oggetti restituiti hanno il %s%% di probabilità di rompersi nel processo! -oc:tooltip.disk=Mezzo primitivo che può essere utilizzato per costruire dispositivi di memorizzazione persistente. -oc:tooltip.diskdrive.CC=Floppy di ComputerCraft sono §asupportati§7. -oc:tooltip.diskdrive=Permette di leggere e scrivere floppy. Può essere installato in robot per consentire in seguito l'inserimento di floppy. -oc:tooltip.geolyzer=Permette la scansione di durezza dei blocchi della zona circostante. Questa informazione può essere utile per generare ologrammi della zona o per rilevare minerali. -oc:tooltip.graphicscard=Usato per cambiare ciò che è visualizzato sullo schermo.[nl] Risoluzione massima: §f%sx%s§7[nl] Massima profondità di colore: §f%s§7[nl] Operazioni/ciclo: §f%s§7 -oc:tooltip.internetcard=Questa scheda consente di effettuare richieste HTTP e l'utilizzo di socket TCP reali. -oc:tooltip.interweb=Congratulazioni, hai vinto un (1) interweb. È possibile connettersi ad esso utilizzando una scheda di Internet. Attenzione: non alimentare i troll. -oc:tooltip.ironnugget=Una pepita fatta di ferro, ecco perché si chiama Pepita di Ferro, duh ... -oc:tooltip.keyboard=Può essere attaccato agli schermi per consentire la digitazione su di essi. -oc:tooltip.hologram0=Un display volumetrico che può essere controllato da computer per visualizzare le strutture voxel arbitrarie.[nl] Risoluzione: §f48x32x48§7 [nl] Scala massima: §f3x§7 [nl] Profondità di colore: §fMonocromatico§7 -oc:tooltip.hologram1=Un display volumetrico che può essere controllato da computer per visualizzare le strutture voxel arbitrarie.[nl] Risoluzione: §f48x32x48§7 [nl] Scala massima: §f4x§7 [nl] Profondità di colore: §fTricolore§7 -oc:tooltip.linkedcard=Questi sono realizzati a coppie, e possono comunicare solo con la loro scheda associata. Tuttavia, essi possono comunicare attraverso qualsiasi distanza, e anche attraverso le dimensioni. L'energia richiesta per inviare un messaggio però è piuttosto alta. -oc:tooltip.linkedcard_channel=§8Canale: %s§7 -oc:tooltip.materialcosts=Tieni premuto [§f%s§7] per il costo in materiali. -oc:tooltip.materials=Materiali: -oc:tooltip.memory=Necessaria per far funzionare i computer. Più ne hai, più complessi i programmi che possono essere eseguiti. -oc:tooltip.microchip=Il chip precedentemente noto come circuito integrato. Non ho idea del perché questo funziona con la pietrarossa, ma lo fa. -oc:tooltip.motionsensor=In grado di rilevare il movimento di esseri viventi nelle vicinanze. Richiede linea di vista ininterrotta. -oc:tooltip.networkcard=Consente ai computer remoti connessi da altri blocchi (come i cavi) di comunicare con l'invio di messaggi. -oc:tooltip.poweracceptor=Velocità di conversione di energia: §f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§fBuildCraft MJ§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§fFactorization Charge§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fIndustrialCraft² EU§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§fMekanism Joules§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fThermal Expansion RF§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fResonant Engine Coulombs§7: §a%s:%s§7 -oc:tooltip.powerconverter=Converte l'energia da altri mod nel tipo di energia interna. Tassi di conversione: -oc:tooltip.powerdistributor=Distribuisce l'eenergia tra reti diverse. Questo è utile per la condivisione di energia immessa nel sistema da un convertitore tra le diverse sotto-reti che dovrebbero rimanere separati. -oc:tooltip.printedcircuitboard=L'elemento di base per schede di espansione, per la memoria e così via. -oc:tooltip.rawcircuitboard=Può essere indurito in qualsiasi forno o fornace compatibile. -oc:tooltip.redstone=Permette la lettura e l'emissione di segnali di pietrarossa attorno tutto il blocco. Può essere controllato da qualsiasi computer che è collegato. Questo è fondamentalmente come una scheda di pietrarossa esterna. -oc:tooltip.redstonecard.ProjectRed=§fProjectRed§7 è §asupportato§7. -oc:tooltip.redstonecard.RedLogic=§fRedLogic§7 è §asupportato§7. -oc:tooltip.redstonecard.RedNet=§fRedNet§7 è §asupportato§7. -oc:tooltip.redstonecard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 è §asupportato§7. -oc:tooltip.redstonecard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 è §asupportato§7. -oc:tooltip.redstonecard=Permette la lettura e l'emissione di segnali di pietrarossa attorno tutto il computer o robot. -oc:tooltip.robot=A differenza dei computer, i robot possono muoversi e interagire con il mondo, molto simile a come può fare un giocatore. Tuttavia §onon§7 possono interagire con componenti esterni!U -# the underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fLivelli§7: §a%s§7 -oc:tooltip.robot_storedenergy=§fEnergia immagazzinata§7: §a%s§7 -oc:tooltip.screen=Mostra del testo, contollato da una scheda grafica contenuta nel case del computer.[nl] Risoluzione massima: §f%sx%s§7[nl] Profondità di colore massima: §f%s§7 -oc:tooltip.server=Questo è un server, ci sono tanti come lui, ma questo può essere aggiornato con i componenti in modo simile a un case del computer. Può essere avviato inserendolo in un rack di server. -oc:tooltip.server.Components=Componenti installati: -oc:tooltip.rack=Permette l'installazione di un massimo di quattro server. Utilizzare un terminale remoto per accedere ai server contenuti in questo server rack. -oc:tooltip.switch=Consente il collegamento di reti diverse tra loro. Solo i messaggi di rete saranno inoltrati attraverso il blocco, i componenti non saranno invece visibili Utilizzarlo per separare le reti pur consentendo la comunicazione utilizzando schede di rete, per esempio. -oc:tooltip.tablet=Un computer tablet, per del Lua fresco in movimento. Può essere forzato lo spegnimento usandolo mentre si preme maiusc. -oc:tooltip.tabletcase=Case di base per i tablet. Posizionarlo in assembler per aggiungere componenti e creare un tablet PC. -oc:tooltip.terminal=Permette il controllo di un server in remoto, fino a quando si è nella portata di esso. Agisce come uno schermo portatile e una tastiera. Utilizzare i tasti maiusc-destro del mouse su un server in un rack di server per associare il terminale ad esso. -oc:tooltip.livello=§8Livello %s -oc:tooltip.toolong=Tenere premuto [§f%s§7] per un tooltip dettagliato. -oc:tooltip.transistor=Un elemento fondamentale in molte altre parti del computer. È un po' contorto, ma fa il suo lavoro. -oc:tooltip.upgradeangel=Consente ai robot di posizionare i blocchi nel nulla, anche se non vi è alcun blocco di riferimento. -oc:tooltip.upgradebattery=Aumenta la quantità di energia che un robot è in grado di immagazzinare, permettendogli di lavorare più a lungo senza dover essere ricaricato. [nl] capacità: §f%s§7 -oc:tooltip.upgradechunkloader=Se un robot si muove in una foresta e non c'è nessuno intorno per vederlo, si muove veramente? Questo aggiornamento consente di essere certi che lo faccia. Mantiene il chunk dove si trova il robot caricato, ma consuma continuamente energia, mentre è attivo. -oc:tooltip.upgradecontainercard=Questo aggiornamento consente l'installazione e la rimozione di schede da un robot assemblato dinamicamente. [nl] Livello massimo: §f%s§7 -oc:tooltip.upgradecontainerupgrade=Questo aggiornamento consente l'installazione e la rimozione di upgrade da un robot assemblato dinamicamente. [nl] Livello massimo: §f%s§7 -oc:tooltip.upgradecrafting=Consente robot per utilizzare l'area in alto a sinistra del loro inventario per il crafting di oggetti. Gli oggetti devono essere allineati come sarebbero in un banco da lavoro. -oc:tooltip.upgradeexperience=Questo aggiornamento consente di robot di accumulare esperienza, quando effettuano diverse operazioni. Maggiore è la loro esperienza, più energia sono in grado di memorizzare, più velocemente possono raccogliere blocchi e più efficientemente utilizzano gli strumenti. -oc:tooltip.upgradegenerator=Può essere usato per generare energia dal combustibile mentre si è in movimento. Brucia oggetti per produrre energia nel corso del tempo, in base al loro valore di carburante.[nl] §fEfficienza§7: §a%s%%§7 -oc:tooltip.upgradeinventory=Questo aggiornamento fornisce spazio nell'inventario al robot. Senza uno di questi, i robot non saranno in grado di immagazzinare gli oggetti internamente. -oc:tooltip.upgradeinventorycontroller=Questo aggiornamento permette al robot più controllo nel modo in cui interagisce con gli inventari esterni, e gli permette di scambiare il suo strumento equipaggiato con uno nel suo inventario. -oc:tooltip.upgradenavigation=Può essere usato per determinare la posizione e l'orientamento del robot. La posizione è relativa al centro della mappa che è stata utilizzata per il crafting tale aggiornamento. -oc:tooltip.upgradepiston=Questo aggiornamentp è molto spinto. Permette di spingere i blocchi, in modo simile ad un pistone. Tuttavia §lnon§7 muove le entità. -oc:tooltip.upgradesign=Consente la lettura del testo e sulla scrittura del testo sui cartelli. -oc:tooltip.upgradesolargenerator=Può essere usato per generare energia dalla luce del sole. Richiede una chiara linea di vista verso il cielo sopra il robot. Genera energia al %s%% della velocità di un motore Stirling. -oc:tooltip.upgradetank=Questo aggiornamento fornisce un serbatoio per lo stoccaggio di liquidi al robot. Senza uno di questi, i robot non saranno in grado di immagazzinare i fluidi internamente. -oc:tooltip.upgradetankcontroller=Questo aggiornamento permette al robot più controllo nel modo in cui interagisce con serbatoi esterni, e permette di trasferire i fluidi dentro e fuori dal serbatoio nel suo inventario. -oc:tooltip.upgradetractorbeam=Dota il robot con tecnologia estremamente avanzata, soprannominato il "Magnet Item". Consente a raccogliere oggetti ovunque entro 3 blocchi dalla sua posizione. -oc:tooltip.wirelessnetworkcard=Consente invio di messaggi wireless in aggiunta a quelli normali. È possibile regolare la §fpotenza del segnale§7 per controllare quanto lontano i messaggi vengono inviati. Una più elevata potenza del segnale richiede un maggior consumo energetico. diff --git a/src/main/resources/assets/opencomputers/lang/it_it.json b/src/main/resources/assets/opencomputers/lang/it_it.json new file mode 100644 index 0000000000..56be5eaaaa --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/it_it.json @@ -0,0 +1,260 @@ +{ + "tile.oc.accesspoint": "Punto di Accesso", + "tile.oc.adapter": "Adattatore", + "tile.oc.assembler": "Assemblatore Elettronico", + "tile.oc.cable": "Cavo", + "tile.oc.capacitor": "Condendatore", + "tile.oc.case1": "Computer Case (Livello 1)", + "tile.oc.case2": "Computer Case (Livello 2)", + "tile.oc.case3": "Computer Case (Livello 3)", + "tile.oc.casecreative": "Computer Case (Creativo)", + "tile.oc.charger": "Caricabatterie", + "tile.oc.disassembler": "Disassemblatore", + "tile.oc.diskdrive": "Unità Disco", + "tile.oc.geolyzer": "Geolyzer", + "tile.oc.keyboard": "Tastiera", + "tile.oc.hologram1": "Proiettore Ologrammi (Livello 1)", + "tile.oc.hologram2": "Proiettore Ologrammi (Livello 2)", + "tile.oc.motionsensor": "Sensore di Movimento", + "tile.oc.powerconverter": "Convertitore di Energia", + "tile.oc.powerdistributor": "Distributore di Energia", + "tile.oc.redstone": "Pietrarossa I/O", + "tile.oc.robot": "Robot", + "tile.oc.robotafterimage": "Robot", + "tile.oc.screen1": "Schermo (Livello 1)", + "tile.oc.screen2": "Schermo (Livello 2)", + "tile.oc.screen3": "Schermo (Livello 3)", + "tile.oc.rack": "Rack", + "tile.oc.switch": "Switch", + "item.oc.abstractbuscard": "Scheda Bus Astratto", + "item.oc.acid": "Grog", + "item.oc.alu": "Unità Aritmetica Logica (ALU)", + "item.oc.analyzer": "Analizzatore", + "item.oc.arrowkeys": "Tasti Freccia", + "item.oc.buttongroup": "Gruppo di Pulsanti", + "item.oc.cardbase": "Scheda Base", + "item.oc.circuitboard": "Circuito", + "item.oc.controlunit": "Unità di Controllo (CU)", + "item.oc.componentbus0": "Bus Periferiche (Livello 1)", + "item.oc.componentbus1": "Bus Periferiche (Livello 2)", + "item.oc.componentbus2": "Bus Periferiche (Livello 3)", + "item.oc.cpu0": "Unità di Elaborazione Centrale (CPU) (Livello 1)", + "item.oc.cpu1": "Unità di Elaborazione Centrale (CPU) (Livello 2)", + "item.oc.cpu2": "Unità di Elaborazione Centrale (CPU) (Livello 3)", + "item.oc.cuttingwire": "Taglierina", + "item.oc.debugcard": "Scheda di Debug", + "item.oc.disk": "Disco", + "item.oc.floppydisk": "Disco Floppy", + "item.oc.graphicscard0": "Scheda Grafica (Livello 1)", + "item.oc.graphicscard1": "Scheda Grafica (Livello 2)", + "item.oc.graphicscard2": "Scheda Grafica (Livello 3)", + "item.oc.harddiskdrive0": "Disco Rigido (Livello 1)", + "item.oc.harddiskdrive1": "Disco Rigido (Livello 2)", + "item.oc.harddiskdrive2": "Disco Rigido (Livello 3)", + "item.oc.internetcard": "Scheda Internet", + "item.oc.interweb": "Interweb", + "item.oc.ironnugget": "Pepita di Ferro", + "item.oc.linkedcard": "Scheda Collegata", + "item.oc.memory0": "Memoria (Livello 1)", + "item.oc.memory1": "Memoria (Livello 1.5)", + "item.oc.memory2": "Memoria (Livello 2)", + "item.oc.memory3": "Memoria (Livello 2.5)", + "item.oc.memory4": "Memoria (Livello 3)", + "item.oc.memory5": "Memoria (Livello 3.5)", + "item.oc.microchip0": "Microchip (Livello 1)", + "item.oc.microchip1": "Microchip (Livello 2)", + "item.oc.microchip2": "Microchip (Livello 3)", + "item.oc.networkcard": "Scheda di Rete", + "item.oc.numpad": "Tastierino Numerico", + "item.oc.printedcircuitboard": "Circuito Stampato (PCB)", + "item.oc.rawcircuitboard": "Circuito Grezzo", + "item.oc.redstonecard0": "Scheda Pietrarossa (Livello 1)", + "item.oc.redstonecard1": "Scheda Pietrarossa (Livello 2)", + "item.oc.server0": "Server (Livello 1)", + "item.oc.server1": "Server (Livello 2)", + "item.oc.server2": "Server (Livello 3)", + "item.oc.server3": "Server (Creativo)", + "item.oc.tablet": "Tablet", + "item.oc.tabletcase0": "Custodia Tablet (Livello 1)", + "item.oc.tabletcase1": "Custodia Tablet (Livello 2)", + "item.oc.tabletcase3": "Custodia Tablet (Creativo)", + "item.oc.terminal": "Terminale Remoto", + "item.oc.transistor": "Transistor", + "item.oc.upgradeangel": "Upgrade Angel", + "item.oc.upgradebattery0": "Upgrade Batteria (Livello 1)", + "item.oc.upgradebattery1": "Upgrade Batteria (Livello 2)", + "item.oc.upgradebattery2": "Upgrade Batteria (Livello 3)", + "item.oc.upgradechunkloader": "Upgrade Chunkloader", + "item.oc.upgradecontainercard0": "Contenitore Schede (Livello 1)", + "item.oc.upgradecontainercard1": "Contenitore Schede (Livello 2)", + "item.oc.upgradecontainercard2": "Contenitore Schede (Livello 3)", + "item.oc.upgradecontainerupgrade0": "Upgrade Contenitore (Livello 1)", + "item.oc.upgradecontainerupgrade1": "Upgrade Contenitore (Livello 2)", + "item.oc.upgradecontainerupgrade2": "Upgrade Contenitore (Livello 3)", + "item.oc.upgradecrafting": "Upgrade Crafting", + "item.oc.upgradeexperience": "Upgrade Esperienza", + "item.oc.upgradegenerator": "Upgrade Generatore", + "item.oc.upgradeinventory": "Upgrade Inventario", + "item.oc.upgradeinventorycontroller": "Upgrade Controllore Inventario", + "item.oc.upgradenavigation": "Upgrade Navigazione", + "item.oc.upgradepiston": "Upgrade Pistoni", + "item.oc.upgradesign": "Upgrade I/O Cartelli", + "item.oc.upgradesolargenerator": "Upgrade Panneli Solari", + "item.oc.upgradetank": "Upgrade Taniche", + "item.oc.upgradetankcontroller": "Upgrade Controllore Taniche", + "item.oc.upgradetractorbeam": "Upgrade Raggio Traente", + "item.oc.wirelessnetworkcard0": "Scheda di Rete Wireless (Livello 1)", + "item.oc.wirelessnetworkcard1": "Scheda di Rete Wireless (Livello 2)", + "itemGroup.OpenComputers": "OpenComputers", + "oc:gui.Analyzer.Address": "§6Indirizzo§f: %s", + "oc:gui.Analyzer.AddressCopied": "Indirizzo copiato negli appunti.", + "oc:gui.Analyzer.ChargerSpeed": "§6Velocità ricarica§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Nome componente§f: %s", + "oc:gui.Analyzer.Components": "§6Numero componenti connessi§f: %s", + "oc:gui.Analyzer.LastError": "§6Ultimo errore§f: %s", + "oc:gui.Analyzer.RobotName": "§6Nome§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Proprietario§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Esperienza§f: %s (Livelli %s)", + "oc:gui.Analyzer.StoredEnergy": "§6Energia immagazzinata§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Totale energia immagazzinata§f: %s", + "oc:gui.Analyzer.Users": "§6Utenti§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6Potenza segnale§f: %s", + "oc:gui.Assembler.Collect": "Collect output", + "oc:gui.Assembler.Complexity": "Complessità: %s/%s", + "oc:gui.Assembler.InsertCase": "Inserisci un case", + "oc:gui.Assembler.InsertCPU": "Inserisci una CPU", + "oc:gui.Assembler.InsertRAM": "Inserisci della RAM", + "oc:gui.Assembler.Progress": "Progresso: %s%% (%s)", + "oc:gui.Assembler.Run": "Assembla", + "oc:gui.Assembler.Warnings": "§eAttenzione§7: Mancano i componenti raccomandati.", + "oc:gui.Assembler.Warning.GraphicsCard": "Scheda Grafica", + "oc:gui.Assembler.Warning.Inventory": "Upgrade Inventario", + "oc:gui.Assembler.Warning.Keyboard": "Tastiera", + "oc:gui.Assembler.Warning.OS": "Disco di Boot", + "oc:gui.Assembler.Warning.Screen": "Schermo", + "oc:gui.Chat.NewVersion": "Una nuova versione è disponibile: %s", + "oc:gui.Chat.WarningFingerprint": "§cATTENZIONE§f - mancata corrispondenza dei fingerprint! Atteso '§a%s§f' ma ottenuto '§e%s§f'. Tranne nel caso tu sia un mod che stai utilizzando una versione decomppilata, è §lfortemente§f raccomantado riscaricare OpenComputers, perché il file JAR che stai utilizzando potrebbe essere stato corrotto.", + "oc:gui.Chat.WarningLuaFallback": "Le librerie Lua Native non sono disponibili, i computers non saranno in gredo di mantenere il loro stato di persostenza. Essi verranno riavviati quando il chunk viene ricaricato.", + "oc:gui.Chat.WarningProjectRed": "Stai utilizzando una versione di Project: Red che è incompatibile con OpenComputers. Prova ad aggriornare la tua versione di Project: Red.", + "oc:gui.Error.ComponentOverflow": "Troppi componenti connessi al computer.", + "oc:gui.Error.InternalError": "Errore interno, per favore vedi il file di log. Questo è probabilmente un bug.", + "oc:gui.Error.NoCPU": "Nessuna CPU instllata nel computer.", + "oc:gui.Error.NoEnergy": "Energia insufficiente.", + "oc:gui.Error.NoRAM": "Nessuna RAM installata nel computer.", + "oc:gui.Error.OutOfMemory": "Memoria esaurita.", + "oc:gui.Robot.Power": "Energia", + "oc:gui.Robot.TurnOff": "Spegni", + "oc:gui.Robot.TurnOn": "Accendi", + "oc:gui.Rack.None": "Nessuno", + "oc:gui.Rack.Back": "Indietro", + "oc:gui.Rack.Bottom": "Basso", + "oc:gui.Rack.Left": "Sinistra", + "oc:gui.Rack.Right": "Destra", + "oc:gui.Rack.Top": "Alto", + "oc:gui.Switch.TransferRate": "Tasso di ciclo", + "oc:gui.Switch.PacketsPerCycle": "Pacchetti / ciclo", + "oc:gui.Switch.QueueSize": "Dimensione coda", + "oc:gui.Terminal.InvalidKey": "Tasto invalido, molto probabilmente un altro terminale è stato collegato al server.", + "oc:gui.Terminal.OutOfRange": "Nessun segnale", + "oc:container.accesspoint": "Punto di accesso", + "oc:container.adapter": "Adattatore", + "oc:container.charger": "Caricabatterie", + "oc:container.case": "Computer", + "oc:container.disassembler": "Disassemblatore", + "oc:container.diskdrive": "Unità Disco", + "oc:container.server": "Server", + "oc:container.rack": "Rack", + "oc:container.switch": "Switch", + "oc:container.tabletwrapper": "Tablet", + "key.opencomputers.materialCosts": "Mostra Costi Materiali", + "key.opencomputers.clipboardPaste": "Copia negli Appunti", + "oc:tooltip.accesspoint": "Funziona come uno Switch, ma può anche ricevere pacchetti wireless ed inoltrare pacchetti ricevuti via cavo in modo wireless.", + "oc:tooltip.abstractbuscard": "Consente di interagire con il bus astratto di §fStargateTech 2§7 inviando e ricevendo pacchetti LIP.", + "oc:tooltip.acid": "Un liquido altamente tossico, normalmente consumato solo da alcuni pirati. Grazie alla sua natura corrosiva è particolarmente adatto per l'incisione dei circuiti stampati.", + "oc:tooltip.adapter": "Utilizzato per controllare blocchi che non sono componenti, come blocchi vanilla di minecraft e blocchi di altri mod.", + "oc:tooltip.alu": "Calcola le somme così non devi farlo tu. Potrebbe essere meglgio così.", + "oc:tooltip.analyzer": "Utilizzato per mostrare informazioni riguardo i blocchi, come il loro §findirizzo§7 e il loro §fnome del componente§7.\nInoltre mostra gli errori che hanno causato un crash del computer, se non è stato spento normalmente.", + "oc:tooltip.assembler": "Permette di costruire robot e altri dispositivi da un certo numero di parti di computer.", + "oc:tooltip.cable": "Un modo economico per connettere i blocchi.", + "oc:tooltip.capacitor": "Immagazzina energia per un uso successivo. Può essere riempito e svuotato molto rapidamente.", + "oc:tooltip.cardbase": "Come indica il nome, questo è l'elemento di base per tutte le schede di espansione.", + "oc:tooltip.case": "Il case del computer è l'elemento di base per i computer e ospita le §fschede di espansione§7, la §fRAM§7 e il §fdisco rigido§7.\nSlots: §f%s§7", + "oc:tooltip.charger": "Trasferisce energia nei robot adiacenti. La velocità di trasferimento dipende dal §fsegnale di pietrarossa§7 applicato, dove nessun segnale significa di non ricaricare i robot e segnale massimo significa ricarica alla massima velocità.", + "oc:tooltip.circuitboard": "Ora stiamo ottenendo qualcosa. Può essere inciso per ottenere un circuito stampato.", + "oc:tooltip.controlunit": "Questa è l'unità che ... controlla ... cose. È necessario per costruire una CPU. Quindi sì, è assolutamente importante.", + "oc:tooltip.componentbus": "Questa espansione consente ai server di comunicare con più componenti, allo stesso tempo, in modo simile a come fanno le CPU.\nComponenti supportati: §f%s§7", + "oc:tooltip.cpu": "Una componente essenziale di tutti i computer. La frequenza di clock è un po' inaffidabile, ma cosa vi aspettate quando viene eseguito da una meridiana tascabile?\nComponenti supportati: §f%s§7", + "oc:tooltip.cpu.Architecture": "Architettura: §f%s§7", + "oc:tooltip.cuttingwire": "Usato per tagliare i blocchi di argilla in circuiti. Si rompe dopo l'uso, che rende probabilmente lo rende strumento più inefficiente mai visto.", + "oc:tooltip.debugcard": "Oggetto per la modalità creativa, permette manipolare il mondo per rendere il testing più facile. Utilizzare a proprio rischio e pericolo.", + "oc:tooltip.disassembler": "Separa gli oggetti nelle loro componenti originali. §lAttenzione§7: gli oggetti restituiti hanno il %s%% di probabilità di rompersi nel processo!", + "oc:tooltip.disk": "Mezzo primitivo che può essere utilizzato per costruire dispositivi di memorizzazione persistente.", + "oc:tooltip.diskdrive.CC": "Floppy di ComputerCraft sono §asupportati§7.", + "oc:tooltip.diskdrive": "Permette di leggere e scrivere floppy. Può essere installato in robot per consentire in seguito l'inserimento di floppy.", + "oc:tooltip.geolyzer": "Permette la scansione di durezza dei blocchi della zona circostante. Questa informazione può essere utile per generare ologrammi della zona o per rilevare minerali.", + "oc:tooltip.graphicscard": "Usato per cambiare ciò che è visualizzato sullo schermo.\nRisoluzione massima: §f%sx%s§7\nMassima profondità di colore: §f%s§7\nOperazioni/ciclo: §f%s§7", + "oc:tooltip.internetcard": "Questa scheda consente di effettuare richieste HTTP e l'utilizzo di socket TCP reali.", + "oc:tooltip.interweb": "Congratulazioni, hai vinto un (1) interweb. È possibile connettersi ad esso utilizzando una scheda di Internet. Attenzione: non alimentare i troll.", + "oc:tooltip.ironnugget": "Una pepita fatta di ferro, ecco perché si chiama Pepita di Ferro, duh ...", + "oc:tooltip.keyboard": "Può essere attaccato agli schermi per consentire la digitazione su di essi.", + "oc:tooltip.hologram0": "Un display volumetrico che può essere controllato da computer per visualizzare le strutture voxel arbitrarie.\nRisoluzione: §f48x32x48§7\nScala massima: §f3x§7\nProfondità di colore: §fMonocromatico§7", + "oc:tooltip.hologram1": "Un display volumetrico che può essere controllato da computer per visualizzare le strutture voxel arbitrarie.\nRisoluzione: §f48x32x48§7\nScala massima: §f4x§7\nProfondità di colore: §fTricolore§7", + "oc:tooltip.linkedcard": "Questi sono realizzati a coppie, e possono comunicare solo con la loro scheda associata. Tuttavia, essi possono comunicare attraverso qualsiasi distanza, e anche attraverso le dimensioni. L'energia richiesta per inviare un messaggio però è piuttosto alta.", + "oc:tooltip.linkedcard_channel": "§8Canale: %s§7", + "oc:tooltip.materialcosts": "Tieni premuto [§f%s§7] per il costo in materiali.", + "oc:tooltip.materials": "Materiali:", + "oc:tooltip.memory": "Necessaria per far funzionare i computer. Più ne hai, più complessi i programmi che possono essere eseguiti.", + "oc:tooltip.microchip": "Il chip precedentemente noto come circuito integrato. Non ho idea del perché questo funziona con la pietrarossa, ma lo fa.", + "oc:tooltip.motionsensor": "In grado di rilevare il movimento di esseri viventi nelle vicinanze. Richiede linea di vista ininterrotta.", + "oc:tooltip.networkcard": "Consente ai computer remoti connessi da altri blocchi (come i cavi) di comunicare con l'invio di messaggi.", + "oc:tooltip.poweracceptor": "Velocità di conversione di energia: §f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§fBuildCraft MJ§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§fFactorization Charge§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fIndustrialCraft² EU§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§fMekanism Joules§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fThermal Expansion RF§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fResonant Engine Coulombs§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Converte l'energia da altri mod nel tipo di energia interna. Tassi di conversione:", + "oc:tooltip.powerdistributor": "Distribuisce l'eenergia tra reti diverse. Questo è utile per la condivisione di energia immessa nel sistema da un convertitore tra le diverse sotto-reti che dovrebbero rimanere separati.", + "oc:tooltip.printedcircuitboard": "L'elemento di base per schede di espansione, per la memoria e così via.", + "oc:tooltip.rawcircuitboard": "Può essere indurito in qualsiasi forno o fornace compatibile.", + "oc:tooltip.redstone": "Permette la lettura e l'emissione di segnali di pietrarossa attorno tutto il blocco. Può essere controllato da qualsiasi computer che è collegato. Questo è fondamentalmente come una scheda di pietrarossa esterna.", + "oc:tooltip.redstonecard.ProjectRed": "§fProjectRed§7 è §asupportato§7.", + "oc:tooltip.redstonecard.RedLogic": "§fRedLogic§7 è §asupportato§7.", + "oc:tooltip.redstonecard.RedNet": "§fRedNet§7 è §asupportato§7.", + "oc:tooltip.redstonecard.WirelessCBE": "§fWireless Redstone (ChickenBones)§7 è §asupportato§7.", + "oc:tooltip.redstonecard.WirelessSV": "§fWireless Redstone (SlimeVoid)§7 è §asupportato§7.", + "oc:tooltip.redstonecard": "Permette la lettura e l'emissione di segnali di pietrarossa attorno tutto il computer o robot.", + "oc:tooltip.robot": "A differenza dei computer, i robot possono muoversi e interagire con il mondo, molto simile a come può fare un giocatore. Tuttavia §onon§7 possono interagire con componenti esterni!U", + "oc:tooltip.robot_level": "§fLivelli§7: §a%s§7", + "oc:tooltip.robot_storedenergy": "§fEnergia immagazzinata§7: §a%s§7", + "oc:tooltip.screen": "Mostra del testo, contollato da una scheda grafica contenuta nel case del computer.\nRisoluzione massima: §f%sx%s§7\nProfondità di colore massima: §f%s§7", + "oc:tooltip.server": "Questo è un server, ci sono tanti come lui, ma questo può essere aggiornato con i componenti in modo simile a un case del computer. Può essere avviato inserendolo in un rack di server.", + "oc:tooltip.server.Components": "Componenti installati:", + "oc:tooltip.rack": "Permette l'installazione di un massimo di quattro server. Utilizzare un terminale remoto per accedere ai server contenuti in questo server rack.", + "oc:tooltip.switch": "Consente il collegamento di reti diverse tra loro. Solo i messaggi di rete saranno inoltrati attraverso il blocco, i componenti non saranno invece visibili Utilizzarlo per separare le reti pur consentendo la comunicazione utilizzando schede di rete, per esempio.", + "oc:tooltip.tablet": "Un computer tablet, per del Lua fresco in movimento. Può essere forzato lo spegnimento usandolo mentre si preme maiusc.", + "oc:tooltip.tabletcase": "Case di base per i tablet. Posizionarlo in assembler per aggiungere componenti e creare un tablet PC.", + "oc:tooltip.terminal": "Permette il controllo di un server in remoto, fino a quando si è nella portata di esso. Agisce come uno schermo portatile e una tastiera. Utilizzare i tasti maiusc-destro del mouse su un server in un rack di server per associare il terminale ad esso.", + "oc:tooltip.livello": "§8Livello %s", + "oc:tooltip.toolong": "Tenere premuto [§f%s§7] per un tooltip dettagliato.", + "oc:tooltip.transistor": "Un elemento fondamentale in molte altre parti del computer. È un po' contorto, ma fa il suo lavoro.", + "oc:tooltip.upgradeangel": "Consente ai robot di posizionare i blocchi nel nulla, anche se non vi è alcun blocco di riferimento.", + "oc:tooltip.upgradebattery": "Aumenta la quantità di energia che un robot è in grado di immagazzinare, permettendogli di lavorare più a lungo senza dover essere ricaricato.\ncapacità: §f%s§7", + "oc:tooltip.upgradechunkloader": "Se un robot si muove in una foresta e non c'è nessuno intorno per vederlo, si muove veramente? Questo aggiornamento consente di essere certi che lo faccia. Mantiene il chunk dove si trova il robot caricato, ma consuma continuamente energia, mentre è attivo.", + "oc:tooltip.upgradecontainercard": "Questo aggiornamento consente l'installazione e la rimozione di schede da un robot assemblato dinamicamente.\nLivello massimo: §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "Questo aggiornamento consente l'installazione e la rimozione di upgrade da un robot assemblato dinamicamente.\nLivello massimo: §f%s§7", + "oc:tooltip.upgradecrafting": "Consente robot per utilizzare l'area in alto a sinistra del loro inventario per il crafting di oggetti. Gli oggetti devono essere allineati come sarebbero in un banco da lavoro.", + "oc:tooltip.upgradeexperience": "Questo aggiornamento consente di robot di accumulare esperienza, quando effettuano diverse operazioni. Maggiore è la loro esperienza, più energia sono in grado di memorizzare, più velocemente possono raccogliere blocchi e più efficientemente utilizzano gli strumenti.", + "oc:tooltip.upgradegenerator": "Può essere usato per generare energia dal combustibile mentre si è in movimento. Brucia oggetti per produrre energia nel corso del tempo, in base al loro valore di carburante.\n§fEfficienza§7: §a%s%%§7", + "oc:tooltip.upgradeinventory": "Questo aggiornamento fornisce spazio nell'inventario al robot. Senza uno di questi, i robot non saranno in grado di immagazzinare gli oggetti internamente.", + "oc:tooltip.upgradeinventorycontroller": "Questo aggiornamento permette al robot più controllo nel modo in cui interagisce con gli inventari esterni, e gli permette di scambiare il suo strumento equipaggiato con uno nel suo inventario.", + "oc:tooltip.upgradenavigation": "Può essere usato per determinare la posizione e l'orientamento del robot. La posizione è relativa al centro della mappa che è stata utilizzata per il crafting tale aggiornamento.", + "oc:tooltip.upgradepiston": "Questo aggiornamentp è molto spinto. Permette di spingere i blocchi, in modo simile ad un pistone. Tuttavia §lnon§7 muove le entità.", + "oc:tooltip.upgradesign": "Consente la lettura del testo e sulla scrittura del testo sui cartelli.", + "oc:tooltip.upgradesolargenerator": "Può essere usato per generare energia dalla luce del sole. Richiede una chiara linea di vista verso il cielo sopra il robot. Genera energia al %s%% della velocità di un motore Stirling.", + "oc:tooltip.upgradetank": "Questo aggiornamento fornisce un serbatoio per lo stoccaggio di liquidi al robot. Senza uno di questi, i robot non saranno in grado di immagazzinare i fluidi internamente.", + "oc:tooltip.upgradetankcontroller": "Questo aggiornamento permette al robot più controllo nel modo in cui interagisce con serbatoi esterni, e permette di trasferire i fluidi dentro e fuori dal serbatoio nel suo inventario.", + "oc:tooltip.upgradetractorbeam": "Dota il robot con tecnologia estremamente avanzata, soprannominato il \"Magnet Item\". Consente a raccogliere oggetti ovunque entro 3 blocchi dalla sua posizione.", + "oc:tooltip.wirelessnetworkcard": "Consente invio di messaggi wireless in aggiunta a quelli normali. È possibile regolare la §fpotenza del segnale§7 per controllare quanto lontano i messaggi vengono inviati. Una più elevata potenza del segnale richiede un maggior consumo energetico." +} diff --git a/src/main/resources/assets/opencomputers/lang/pt_BR.lang b/src/main/resources/assets/opencomputers/lang/pt_BR.lang deleted file mode 100644 index 6ac0a419f5..0000000000 --- a/src/main/resources/assets/opencomputers/lang/pt_BR.lang +++ /dev/null @@ -1,490 +0,0 @@ -# This is the Brazilian portuguese translation based on master english file. -#Author: Hilton W. Silva (hws689) -# Updated by guilherme-puida in 03/01/2021 - -# Blocks -tile.oc.accesspoint.name=§cPonto de Acesso§7 -tile.oc.adapter.name=Adaptador -tile.oc.assembler.name=Montador Eletrônico -tile.oc.cable.name=Cabo -tile.oc.capacitor.name=Capacitador -tile.oc.carpetedCapacitor.name=Capacitador com Tapete -tile.oc.case1.name=Gabinete (Nível 1) -tile.oc.case2.name=Gabinete (Nível 2) -tile.oc.case3.name=Gabinete (Nível 3) -tile.oc.casecreative.name=Gabinete (Criativo) -tile.oc.chameliumblock.name=Bloco Camaleão -tile.oc.charger.name=Carregador -tile.oc.disassembler.name=Desmontador -tile.oc.diskdrive.name=Unidade de Disco -tile.oc.endstone.name=Pedra do Fim -tile.oc.geolyzer.name=Geonalizador -tile.oc.hologram1.name=Projetor Holográfico (Nível 1) -tile.oc.hologram2.name=Projetor Holográfico (Nível 2) -tile.oc.keyboard.name=Teclado -tile.oc.microcontroller.name=Microcontrolador -tile.oc.motionsensor.name=Sensor de Movimento -tile.oc.netsplitter.name=Divisor de Rede -tile.oc.powerconverter.name=Conversor de Energia -tile.oc.powerdistributor.name=Distribuidor de Energia -tile.oc.print.name=Impressão 3D -tile.oc.printer.name=Impressora 3D -tile.oc.raid.name=Raid -tile.oc.redstone.name= E/S de Redstone -tile.oc.relay.name=Relé -tile.oc.robot.name=Robô -tile.oc.robotafterimage.name=Robô -tile.oc.screen1.name=Monitor (Nível 1) -tile.oc.screen2.name=Monitor (Nível 2) -tile.oc.screen3.name=Monitor (Nível 3) -tile.oc.rack.name=Rack -tile.oc.switch.name=§cSwitch§7 -tile.oc.transposer.name=Transpositor -tile.oc.waypoint.name=Ponto de Passagem - -# Items -item.oc.abstractbuscard.name=Placa de Barramento Abstrata -item.oc.acid.name=Grogue -item.oc.alu.name=Unidade Lógica Aritmética (ULA) -item.oc.analyzer.name=Analizador -item.oc.apu0.name=Unidade de Processamento Acelerado (UPA) (Nível 1) -item.oc.apu1.name=Unidade de Processamento Acelerado (UPA) (Nível 2) -item.oc.apu2.name=Unidade de Processamento Acelerado (UPA) (Criativo) -item.oc.arrowkeys.name=Setas do Teclado -item.oc.buttongroup.name=Grupo de Botões -item.oc.cardbase.name=Base de Cartão -item.oc.chamelium.name=Camaleão -item.oc.circuitboard.name=Placa de Circuito -item.oc.componentbus0.name=Componente de Barramento (Nível 1) -item.oc.componentbus1.name=Componente de Barramento (Nível 2) -item.oc.componentbus2.name=Componente de Barramento (Nível 3) -item.oc.componentbus3.name=Componente de Barramento (Criativo) -item.oc.controlunit.name=Unidade de Controle (UC) -item.oc.cpu0.name=Unidade Central de Processamento (CPU) (Nível 1) -item.oc.cpu1.name=Unidade Central de Processamento (CPU) (Nível 2) -item.oc.cpu2.name=Unidade Central de Processamento (CPU) (Nível 3) -item.oc.cuttingwire.name=Fio de Corte -item.oc.datacard0.name=Cartão de Dados (Nível 1) -item.oc.datacard1.name=Cartão de Dados (Nível 2) -item.oc.datacard2.name=Cartão de Dados (Nível 3) -item.oc.debugcard.name=Cartão de Depuração -item.oc.debugger.name=Depurador de Rede -item.oc.diamondchip.name=Chip de Diamante -item.oc.disk.name=Prato do Disco -item.oc.diskdrivemountable.name=Unidade de Disco -item.oc.drone.name=Drone -item.oc.dronecase0.name=Carcaça de Drone (Nível 1) -item.oc.dronecase1.name=Carcaça de Drone (Nível 2) -item.oc.dronecase3.name=Carcaça de Drone (Criativo) -item.oc.eeprom.name=EEPROM -item.oc.floppydisk.name=Disquete -item.oc.graphicscard0.name=Placa de Vídeo (Nível 1) -item.oc.graphicscard1.name=Placa de Vídeo (Nível 2) -item.oc.graphicscard2.name=Placa de Vídeo (Nível 3) -item.oc.harddiskdrive0.name=Disco Rígido (Nível 1) -item.oc.harddiskdrive1.name=Disco Rígido (Nível 2) -item.oc.harddiskdrive2.name=Disco Rígido (Nível 3) -item.oc.hoverboots.name=Botas Voadoras -item.oc.inkcartridge.name=Cartucho de Tinta -item.oc.inkcartridgeempty.name=Cartucho de Tinta (Vazio) -item.oc.internetcard.name=Cartão de Internet -item.oc.interweb.name=Interweb -item.oc.ironnugget.name=Pepita de Ferro -item.oc.linkedcard.name=Cartão Vinculado -item.oc.manual.name=Manual do OpenComputers -item.oc.memory0.name=Memória (Nível 1) -item.oc.memory1.name=Memória (Nível 1.5) -item.oc.memory2.name=Memória (Nível 2) -item.oc.memory3.name=Memória (Nível 2.5) -item.oc.memory4.name=Memória (Nível 3) -item.oc.memory5.name=Memória (Nível 3.5) -item.oc.microchip0.name=Circuito Integrado (Nível 1) -item.oc.microchip1.name=Circuito Integrado (Nível 2) -item.oc.microchip2.name=Circuito Integrado (Nível 3) -item.oc.microcontrollercase0.name=Carcaça do Microcontrolador (Nível 1) -item.oc.microcontrollercase1.name=Carcaça do Microcontrolador (Nível 2) -item.oc.microcontrollercase3.name=Carcaça do Microcontrolador (Criativo) -item.oc.nanomachines.name=Nanomáquinas -item.oc.networkcard.name=Cartão de Rede -item.oc.numpad.name=Teclado Numérico -item.oc.present.name=Uma coisinha... -item.oc.printedcircuitboard.name=Placa de Circuito Impresso (PCB) -item.oc.rawcircuitboard.name=Placa de Circuito Crua -item.oc.redstonecard0.name=Cartão de Redstone (Nível 1) -item.oc.redstonecard1.name=Cartão de Redstone (Nível 2) -item.oc.server0.name=Servidor (Nível 1) -item.oc.server1.name=Servidor (Nível 2) -item.oc.server2.name=Servidor (Nível 3) -item.oc.server3.name=Servidor (Criativo) -item.oc.tablet.name=Tablet -item.oc.tabletcase0.name=Carcaça de Tablet (Nível 1) -item.oc.tabletcase1.name=Carcaça de Tablet (Nível 2) -item.oc.tabletcase3.name=Carcaça de Tablet (Criativo) -item.oc.terminal.name=Terminal Remoto -item.oc.terminalserver.name=Servidor de Terminal -item.oc.texturepicker.name=Selecionador de Textura -item.oc.transistor.name=Transistor -item.oc.upgradeangel.name=Aprimoramento Angelical -item.oc.upgradebattery0.name=Aprimoramento de Bateria (Nível 1) -item.oc.upgradebattery1.name=Aprimoramento de Bateria (Nível 2) -item.oc.upgradebattery2.name=Aprimoramento de Bateria (Nível 3) -item.oc.upgradechunkloader.name=Aprimoramento de Chunkloader -item.oc.upgradecontainercard0.name=Contêiner de Cartão (Nível 1) -item.oc.upgradecontainercard1.name=Contêiner de Cartão (Nível 2) -item.oc.upgradecontainercard2.name=Contêiner de Cartão (Nível 3) -item.oc.upgradecontainerupgrade0.name=Aprimoramento de Contêiner (Nível 1) -item.oc.upgradecontainerupgrade1.name=Aprimoramento de Contêiner (Nível 2) -item.oc.upgradecontainerupgrade2.name=Aprimoramento de Contêiner (Nível 3) -item.oc.upgradecrafting.name=Aprimoramento de Construção -item.oc.upgradedatabase0.name=Aprimoramento de Banco de Dados (Nível 1) -item.oc.upgradedatabase1.name=Aprimoramento de Banco de Dados (Nível 2) -item.oc.upgradedatabase2.name=Aprimoramento de Banco de Dados (Nível 3) -item.oc.upgradeexperience.name=Aprimoramento de Experiência -item.oc.upgradegenerator.name=Aprimoramento de Gerador -item.oc.upgradehover0.name=Aprimoramento de Flutuação (Nível 1) -item.oc.upgradehover1.name=Aprimoramento de Flutuação (Nível 2) -item.oc.upgradeinventory.name=Aprimoramento de Inventário -item.oc.upgradeinventorycontroller.name=Aprimoramento de Controlador de Inventário -item.oc.upgradeleash.name=Aprimoramento de Correia -item.oc.upgradeMF.name=MFU -item.oc.upgradenavigation.name=Aprimoramento de Navegação -item.oc.upgradepiston.name=Aprimoramento de Pistão -item.oc.upgradesign.name=Aprimoramento de Sinal de E/S -item.oc.upgradesolargenerator.name=Aprimoramento de Gerador Solar -item.oc.upgradetank.name=Aprimoramento de Tanque -item.oc.upgradetankcontroller.name=Aprimoramento de Controlador de Tanque -item.oc.upgradetractorbeam.name=Aprimoramento de Raio Trator -item.oc.upgradetrading.name=Aprimoramento de Troca -item.oc.wirelessnetworkcard0.name=Cartão de Rede Sem Fio (Nível 1) -item.oc.wirelessnetworkcard1.name=Cartão de Rede Sem Fio (Nível 2) -item.oc.worldsensorcard.name=Cartão de Sensor de Mundo -item.oc.wrench.name=Chave de fenda-boca - -# Entities -entity.oc.Drone.name=Drone - -# GUI -oc:gui.Analyzer.Address=§6Endereço§f: %s -oc:gui.Analyzer.AddressCopied=Endereço copiado para a área de transferência. -oc:gui.Analyzer.ChargerSpeed=§6Velocidade da carga§f: %s -oc:gui.Analyzer.ComponentName=§6Nome do componente§f: %s -oc:gui.Analyzer.Components=§6Número de componentes conectados§f: %s -oc:gui.Analyzer.CopyToClipboard=Clique para copiar para a área de transferência. -oc:gui.Analyzer.LastError=§6Último erro§f: %s -oc:gui.Analyzer.RobotName=§6Nome§f: %s -oc:gui.Analyzer.RobotOwner=§6Dono§f: %s -oc:gui.Analyzer.RobotXp=§6Experiência§f: %s (Nível %s) -oc:gui.Analyzer.StoredEnergy=§6Energia armazenada§f: %s -oc:gui.Analyzer.TotalEnergy=§6Total de energia armazenada§f: %s -oc:gui.Analyzer.Users=§6Usuários§f: %s -oc:gui.Analyzer.WirelessStrength=§6Força do sinal§f: %s -oc:gui.Assembler.Collect=Saída do coletador -oc:gui.Assembler.Complexity=Complexidade: %s/%s -oc:gui.Assembler.InsertCase=Insira uma parte base -oc:gui.Assembler.InsertCPU=Insira uma CPU -oc:gui.Assembler.InsertRAM=Insira alguma RAM -oc:gui.Assembler.Progress=Progresso: %s%% (%s) -oc:gui.Assembler.Run=Montar -oc:gui.Assembler.Warning.BIOS=BIOS -oc:gui.Assembler.Warning.GraphicsCard=Placa de Vídeo -oc:gui.Assembler.Warning.Inventory=Aprimoramento de Inventário -oc:gui.Assembler.Warning.Keyboard=Teclado -oc:gui.Assembler.Warning.OS=Mídia Inicializável -oc:gui.Assembler.Warning.Screen=Monitor -oc:gui.Assembler.Warnings=§eAtenção§7: Componentes recomendados ausentes. -oc:gui.Chat.NewVersion=Uma nova versão está disponível: %s -oc:gui.Chat.TextureName=§7Nome da textura é §a%s§f. -oc:gui.Chat.WarningClassTransformer=Houve um erro §cerros§f ao rodar o 'class transformer'. Por favor relate isso, junto com o seu arquivo de log (completo!) FML §alatest.log§f/§afml-server-latest.log§f , obrigado! -oc:gui.Chat.WarningFingerprint=§cATENÇÃO§f - impressão digital não reconhecida! Experado '§a%s§f' mas recebido '§e%s§f'. A não ser que você seja um desenvolvedor e esteja rodando uma versão desofuscada, é §lextremamente§f recomendável que baixe novamente o OpenComputers, por que o JAR que está usando talvez esteja adulterado. -oc:gui.Chat.WarningLink=Não foi possível abrir o atalho: %s -oc:gui.Chat.WarningLuaFallback=Bibliotecas nativas do Lua não disponíveis, computadores não serão capazes de persistir seus estados. Eles reinicializarão quando chunks descarregarem. -oc:gui.Chat.WarningProjectRed=Você está usando uma versão do Project: Red que é incompativel com OpenComputers. Tente atualizar sua versão do Project: Red. -oc:gui.Chat.WarningRecipes=Houve erros ao carregar uma ou mais receitas. Alguns itens não poderão ser construídos. Verifique seu arquivo de log para mais informações. -oc:gui.Chat.WarningSimpleComponent=Um addon (seu?) usa a interface §aSimpleComponent§f que faz §ealgo errado§f. A lógica de componente não pode ser injetada. Por favor verifique seu arquivo de log para mais informações. -oc:gui.Drive.Managed=Gerenciado -oc:gui.Drive.Unmanaged=Não Gerenciado -oc:gui.Drive.ReadOnlyLock=Bloqueado -oc:gui.Drive.ReadOnlyLockWarning=§Somente leitura§r. Isso não pode ser removido, exceto quando o disco é formatado. -oc:gui.Drive.Warning=§lAtençaõ§r: mudança de modos resultará em perca de todos os dados do disco! -oc:gui.Error.ComponentOverflow=Muitos componentes conectados ao computador. -oc:gui.Error.InternalError=Erro interno, por favor veja o arquivo de log. Isto é provavelmente um erro. -oc:gui.Error.NoCPU=Não há CPU instalada no computador. -oc:gui.Error.NoEnergy=Energia insuficiente. -oc:gui.Error.NoRAM=Não há RAM instalada no computador. -oc:gui.Error.OutOfMemory=Sem memória. -oc:gui.Manual.Blocks=Blocos do OpenComputers -oc:gui.Manual.Home=Início -oc:gui.Manual.Items=Itens do OpenComputers -oc:gui.Manual.Warning.BlockMissing=Bloco indisponível. -oc:gui.Manual.Warning.ImageMissing=Imagem não encontrada. -oc:gui.Manual.Warning.ItemMissing=Item indisponível. -oc:gui.Manual.Warning.OreDictMissing=Entrada no dicionário de minérios indisponível. -oc:gui.Raid.Warning=§4Adicionar um disco o formata.[nl] Remover um disco limpa a raid. -oc:gui.Robot.Power=Energia -oc:gui.Robot.TurnOff=Desligar -oc:gui.Robot.TurnOn=Ligar[nl]§7Use um Analizador para verficar problemas.§r -oc:gui.Rack.Back=Voltar -oc:gui.Rack.Bottom=Baixo -oc:gui.Rack.Left=Esquerda -oc:gui.Rack.None=Nenhum -oc:gui.Rack.Right=Direita -oc:gui.Rack.Enabled=Habilitado -oc:gui.Rack.Disabled=Disabilitado -oc:gui.Rack.RelayModeTooltip=Modo de relé -oc:gui.Rack.Top=Cima -oc:gui.Switch.PacketsPerCycle=Pacotes / ciclo -oc:gui.Switch.QueueSize=Tamanho da fila -oc:gui.Switch.TransferRate=Taxa do ciclo -oc:gui.Terminal.InvalidKey=Chave inválida, provavelmente outro terminal foi conectado ao servidor. -oc:gui.Terminal.OutOfRange=Sem sinal. - -# Containers -oc:container.accesspoint=Ponto de Acesso -oc:container.adapter=Adaptador -oc:container.case=Computador -oc:container.charger=Carregador -oc:container.disassembler=Desmontador -oc:container.diskdrive=Unidade de disco -oc:container.printer=Impressora -oc:container.raid=Raid -oc:container.relay=Relé -oc:container.server=Servidor -oc:container.rack=Rack -oc:container.switch=Switch -oc:container.tabletwrapper=Tablet - -# Keybinds -key.clipboardPaste=Colar da área de transferência -key.materialCosts=Mostrar custo dos materiais - -# Item / Block Tooltips -oc:tooltip.accesspoint=Atua como um Switch, mas adicionalmente recebe pacotes sem fio e retransmite pacotes com fio sem fio. -oc:tooltip.abstractbuscard=Permite interagir com o barramento abstrato de §fStargateTech 2§7 enviando e recebendo pacotes LIP. -oc:tooltip.acid=Um pseudo-liquido altamente tóxico, usualmente consumidos por alguns piratas (ihic!). Também, todavia, pode ser útil de outros modos. -oc:tooltip.adapter=Usado para controlar blocos que não são componentes, tal como blocos vanillas ou de outros mods. -oc:tooltip.alu=Adiciona números que você não têm. Bem melhor assim. -oc:tooltip.analyzer=Usado para mostrar informações sobre os blocos, tal como seu §fendereço§7 e §fnome do componente§7.[nl] Também mostra o erro que causou um computador travar se não foi desligado normalmente. -oc:tooltip.apu=Isso é um CPU com um GPU integrado (ou IGP), quando você apenas precisa deste slot de placa .[nl] Componentes Suportados: §f%s§7[nl] Resolução mãxima: §f%sx%s§7[nl] Densidade de cores máxima: §f%s§7[nl] Operações/tick: §f%s§7 -oc:tooltip.assembler=Permite construir robôs e outros dispositivos com várias partes de computador. -oc:tooltip.cable=Uma maneira barata de conectar os blocos. -oc:tooltip.capacitor=Armazena energia para usar mais tarde. Pode ser enchido e esvaziado rapidamente. -oc:tooltip.cardbase=Como o nome diz, este é o bloco de construção básico para os cartões de expansão. -oc:tooltip.carpetedcapacitor=Armazena energia para uso posterior. Pode ser carregado e descarregado rapidamente. Carrega quando uma ovelha ou jaguatirica anda sobre o mesmo. -oc:tooltip.case=O gabinete é o bloco básico para computadores e guarda os §fcartões de extensão§7, §fRAM§7 e §fdiscos rígidos§7.[nl] Slots: §f%s§7 -oc:tooltip.chamelium=Matéria prima para as imressões 3D. Não ingerir: talvez leve a cegueira e um lapso temporário de presença. -oc:tooltip.chameliumblock=Agradável e Limpo. Usado para formas coloridas nas impressões 3D, ou para simplesmente ter, um bloco colorido para decorar sua linda e chamativa base. -oc:tooltip.charger=Transfere energia dos capacitores para robôs e drones adjacentes. A taxa de energia depende do §fsinal de redstone§7 vindo, onde sem sinal não carrega os dispositivos, e quanto mais forte o sinal maior será a velocidade de carregamento. Pode ser usado também para carregar tablets e unidades de disco de acesso em tablets. -oc:tooltip.circuitboard=Agora estamos chegando em algum lugar. Pode ser cozido para obter uma placa de circuito impresso. -oc:tooltip.controlunit=Está é a unidade que... controla... coisas. Você precisa disso para construir a CPU. Então é tipo, totalmente importante. -oc:tooltip.componentbus=Está expansão permite aos servidores comunicarem com mais componentes ao mesmo tempo, similar como os CPUs fazem.[nl] Componentes Suportados: §f%s§7 -oc:tooltip.cpu=Um componente essencial para todos os computadores. O clock (relógio/taxa do processamento) é um tanto quanto que duvidoso, mas o que você espera se ele roda num relógio de sol de bolso?[nl] Componentes Suportados: §f%s§7 -oc:tooltip.cpu.Architecture=Arquitetura: §f%s§7 -oc:tooltip.cuttingwire=Usado para cortar blocos de argila em formato de placas de circuito. Quebra quando usa, o que provavelmente é a pior ferramenta de todas. -oc:tooltip.datacard0=Provê um conjuto de algoritmos tal como hash e desinflar/inflar. -oc:tooltip.datacard1=Provê um conjuto de algoritmos tal como hash, encriptação AES e desinflar/inflar. -oc:tooltip.datacard2=Provê um conjuto de algoritmos tal como hash, encriptação AES, criptografia de curva elíptica e desinflar/inflar. -oc:tooltip.debugcard=Item do modo criativo, permite manipular o mundo para fazer testes facieis. Use por sua conta e risco. -oc:tooltip.debugger=Pode ser usado para depurar informações na grade de rede interna do OC. Somente use se for instruído por um desenvolvedor. -oc:tooltip.diamondchip=Um pedacinho de um diamante uma vez impecável. Ele nunca será o mesmo de novo. -oc:tooltip.disassembler=Separa os itens em seus componentes originais. §lAtenção§7: o item retornado tem uma chance de %s%% de quebrar no processo! -oc:tooltip.disk=Uma mídia primitiva que pode ser usada para construir dispositvos de armazenamentos contínuos. -oc:tooltip.diskdrive.CC=Disquetes do ComputerCraft são §asuportados§7. -oc:tooltip.diskdrive=Permite escrever e ler disquetes. Pode ser instalado em robôs para permitir inserir disquetes mais tarde. -oc:tooltip.diskdrivemountable=Provê a mesma funcionalidade de uma unidade de disco normal, mas só pode ser instalado em um rack. -oc:tooltip.diskusage=Uso de disco: %s/%s Byte -oc:tooltip.disklocked=Bloqueado por: %s -oc:tooltip.diskmodemanaged=Modo: Gerenciado -oc:tooltip.diskmodeunmanaged=Modo: Não gerenciado -oc:tooltip.drone=Drones são leves, com reconhecimento rápido de unidades com espaço interno limitado. -oc:tooltip.dronecase=Está carcaça é usada para montar drones no montador. Ele tem um espaço para uma pequena quantidade de componentes e provê levitação com a pedra do fim. -oc:tooltip.eeprom=Pequeno armazenamento programável que contem a BIOS dos computadores usado para iniciá-los. -oc:tooltip.fakeendstone=Quase igual a coisa real, emula até mesmo sua levitação! -oc:tooltip.geolyzer=Permite escanear a dureza da área ao redor de blocos sólidos. Essa informação pode ser útil para geração de hologramas de área ou para detectar minérios. -oc:tooltip.graphicscard=Usado para mudar o que é mostrado nos monitores.[nl] Máxima resolução: §f%sx%s§7[nl] Máxima profundidade de cores: §f%s§7[nl] Operações/tick: §f%s§7 -oc:tooltip.hoverboots=Pule alto, caia devagar, caminhe melhor. Isso e mais, com as mais novas e patenteadas Botas Voadoras (TM). -oc:tooltip.inkcartridge=Usado para carregar tinta nas impressoras 3D. Por razões misteriosas ele não tem que permanecer na impressora. -oc:tooltip.inkcartridgeempty=Este cartucho de tinta foi usado até secar. Recarregue isso usando corantes. Ou jogue-o fora. Veja minha cara de preocupado -.-. -oc:tooltip.internetcard=Este cartão faz requisições HTTP usa protocolos TCP reais. -oc:tooltip.interweb=Parabéns, você ganhou um (1) interweb. Você pode conectar a isso usando um Cartão de Internet. Cuidado: não alimente os trolls. -oc:tooltip.ironnugget=Uma pepita feita de ferro, por isso é chamado de Pepita de Ferro, darrr... -oc:tooltip.keyboard=Pode ser anexados aos monitores para permitir digitar neles. -oc:tooltip.hologram0=Uma exibição volumétrica que pode ser controlado por computadores para exibir estruturas de voxel arbitrárias.[nl] Resolução: §f48x32x48§7 [nl] Escala máxima: §f3x§7 [nl] Profundidade de cores: §fMonocromatico§7 -oc:tooltip.hologram1=Uma exibição volumétrica que pode ser controlado por computadores para exibir estruturas de voxel arbitrárias.[nl] Resolução: §f48x32x48§7 [nl] Escala máxima: §f4x§7 [nl] Profundidade de cores: §fTricolor§7 -oc:tooltip.linkedcard=Eles são construidos em pares, e só pode comunicar-se com seu par. Entretanto, eles podem se comunicar em qualquer distância, e também cruzar dimensões. A energia requerida para enviar a mensagem é altíssima. -oc:tooltip.linkedcard_channel=§8Canal: %s§7 -oc:tooltip.manual=Toda informaçâo que você provalvemente precisará do OpenComputers. E mais. Por um preço inacreditável de... §opor favor pressiona R para continuar§7. -oc:tooltip.materialcosts=Segure [§f%s§7] para custos do material. -oc:tooltip.materials=Materiais: -oc:tooltip.memory=Requerida para fazer os computadores funcionarem. Quanto mais tiver, mais complexos podem ser os programas. -oc:tooltip.microchip=Um chip conhecido formalmente como Circuito Integrado. Eu não tenho ideia porque isso funciona com redstone, mas funciona. -oc:tooltip.microcontroller=Microcontroladores são mini computadores. Eles são usadas para cuidar de tarefas específicas, rodando um único programa que é provido pela EEPROM consruida dentro dele.[nl] §cNão pode conectar com componentes externos.§7 -oc:tooltip.microcontrollercase=Componente básico para construir microcontroladores. Coloque-o em um montador para adicionar novos componentes e montar um microcontrolador. -oc:tooltip.motionsensor=Pode detectar movimento de formas de vidas próximas. Requer visão direta. -oc:tooltip.nanomachines=Unidade de controle e um grupo de nanomáquinas pra ingerir, se você tiver coragem. -oc:tooltip.networkcard=Permite que computadores distantes conectem por outros blocos (como cabos) para comunicar-se enviando mensagens um para o outro. -oc:tooltip.poweracceptor=Velocidade da conversão de energia: §f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§fBuildCraft MJ§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§fCarregamento do Factorization§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fIndustrialCraft² EU§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§fMekanism Joules§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fThermal Expansion RF§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fResonant Engine Coulombs§7: §a%s:%s§7 -oc:tooltip.powerconverter=Converte energia de outros mods para o tipo de energia interna. Taxa de conversão: -oc:tooltip.powerdistributor=Distribui energia por meio de diferentes redes. Isto é útil para compartilhar fluxo de energia de seu sistema para outro conversor em diferentes sub-redes que podem manter separados. -oc:tooltip.present=... para seus problemas. Abra este presente para ter uma chance de receber §kum grande tesouro§7![nl]§8Construa itens do OpenComputers para ter uma chance de receber presente.§7 -oc:tooltip.print.BeaconBase=§8Funciona como uma base do sinalizador. -oc:tooltip.print.LightValue=§8Luz emitida: %s. -oc:tooltip.print.RedstoneLevel=§8Saída da Redstone: %s. -oc:tooltip.printedcircuitboard=O bloco de construção básico para cartões de expansão, memória e outros. -oc:tooltip.printer=Permite imprimir blocos com forma definida pelo usuário usando o Camaleão (nome lindo?) e Cartucho de Tinta. Deve ser configurado usando um computador. Deixe longe do alcance das crianças. Porque sim. -oc:tooltip.raid=Permite cobinar três discos rigídos em um único grande arquivo de sistema que pode ser usado por todos os computadores conectados. -oc:tooltip.rawcircuitboard=Pode ser endurecido em qualquer fornalha compátivel. -oc:tooltip.redstone=Permite ler e emitir sinais de redstone ao redor do bloco. Pode ser controlado por qualquer computador que o bloco estiver conectado. Isto é básicamente um cartão de redstone externo. -oc:tooltip.redstonecard.ProjectRed=§fProjectRed§7 é §asuportado§7. -oc:tooltip.redstonecard.RedLogic=§fRedLogic§7 é §asuportado§7. -oc:tooltip.redstonecard.RedNet=§fRedNet§7 é §asuportado§7. -oc:tooltip.redstonecard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 é §asuportado§7. -oc:tooltip.redstonecard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 é §asuportado§7. -oc:tooltip.redstonecard=Permite ler e emitir sinais de redstone ao redor do robô computadorizado. -oc:tooltip.relay=Permite conectar diversas redes uma com a outra. Somente mensagens de rede serão passadas, componentes não serão vísiveis através disto. Use para separar redes e continuar permitindo comunicação usando Cartões de Rede, por exemplo. -oc:tooltip.robot=Diferente de computadores, robôs podem mover-se por ai e interagir com o mundo parecido com o que um jogador faz.[nl] §cNão pode conectar-se com componentes externos.§7 -# The underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fNível§7: §a%s§7 -oc:tooltip.robot_storedenergy=§fEnergia armazenada§7: §a%s§7 -oc:tooltip.screen=Mostra texto, controlado por uma placa de vídeo em um Gabinete.[nl] Resolução máxima: §f%sx%s§7[nl] Densidade máxima: §f%s§7 -oc:tooltip.server=Isto é um servidor: existem muitos como este, mas este pode ser aprimorado com componentes como um gabinete pode ser. Ele pode ser ligado inserindo-o em um rack de servidor. -oc:tooltip.server.Components=Componentes instalados: -oc:tooltip.rack=Permite a instalação de até quatro servidores ou outros montáveis. -oc:tooltip.switch=Permite conectar várias redes uma com a outra. Somente mensagens de rede serão transmitidas, componentes não serão vísiveis. Use-o para separar redes permitindo comunicação usando Cartões de Rede, por exemplo. -oc:tooltip.tablet=Um tablet, para usar Lua de maneira portátil. Pode ser forçado a desligar se abaixando e ativando-o. -oc:tooltip.tabletcase=Carcaça básica para tablets. Coloque-o no montador para adicionar componentes e criar um tablet. -oc:tooltip.terminal=Permite controlar um servidor remotamente, enquanto estiver no seu alcance. Atua como monitor e teclados portateis. Shift + Botão Direito em um servidor em um rack para vincular um terminal. -oc:tooltip.terminalserver=Backend para que Terminais remotos possam ser conectados para prover controle remoto. Contém um monitor virtual e um teclado. -oc:tooltip.texturepicker=Esta ferramente mostra uma string descrevendo uma superfície de bloco, para usar na impressora 3D e definir formas. Não são nomes de texturas, nana nina não. -oc:tooltip.tier=§8Nível %s -oc:tooltip.netsplitter=Atua como um conector dinâmico. Conectividade de cada lado pode ser mudada batendo-a com uma chave. Conectividade de todos os lados podem ser invertidas aplicando um sinal de redstone. -oc:tooltip.toolong=Segure [§f%s§7] para uma dica detalhada. -oc:tooltip.transistor=Um elemento básico para outras partes de computador. É um pouco torto, mas faz seu trabalho. -oc:tooltip.transposer=Permite transferir automaticamente itens e fluidos entre inventários adjacentes e recipientes de fluidos. -oc:tooltip.upgradeangel=Permite que robôs coloquem blocos no ar, mesmo sem um ponto de apoio. -oc:tooltip.upgradebattery=Aumenta a quantidade de energia que o dispositivo pode armazenar, permitindo que trabalhe mais tempo sem precisa recarregar. [nl] Capacidade: §f%s§7 -oc:tooltip.upgradechunkloader=Se um robô move-se em uma floresta e ninguém é capaz de ver ele, ele está se mexendo ou não? Este aprimoramento faz ter certeza que sim. Isto mantêm um chunk em que um dispositvo está carregado, mas consome energia continuamente enquanto ativo. -oc:tooltip.upgradecontainercard=Este aprimoramento de contêiner permite dinamicamente instalar e remover um cartão de um dispositivo montado. [nl] Nível máximo: §f%s§7 -oc:tooltip.upgradecontainerupgrade=Este aprimoramento de contêiner permite dinamicamente instalar e remover outro aprimoramento de um dispositivo montado. [nl] Nível máximo: §f%s§7 -oc:tooltip.upgradecrafting=Permite que robôs usem o canto superior esquerdo de seu inventário para construir objetos. Os itens devem estar posicionados como se estivessem numa mesa de trabalho. -oc:tooltip.upgradedatabase=Este aprimoramento permite armazenar informação de pilha de itens para ser usado por outros componentes.[nl] Entradas suportadas: §f%s§7 -oc:tooltip.upgradeexperience=Este aprimoramento permite que robôs acumulem experiência efetuando diversas operações. Quanto mais experiência estiver, mais energia pode armazenar, mais rápido pode cortar blocos e mais efeciente ele usa as ferramentas. -oc:tooltip.upgradegenerator=Pode ser usado para gerar combustível em movimento. Queima itens para gerar energia o tempo todo, baseado em seus valores de combustível.[nl] §fEfeciencia§7: §a%s%%§7 -oc:tooltip.upgradehover=Este aprimoramento permite que robôs voem acima do solo sem precisar escalar paredes.[nl] Altura máxima: §f%s§7 -oc:tooltip.upgradeinventory=Este aprimoramento provê espaço no inventário para robôs ou drones. Sem um destes, eles não serão capazes de armazenar itens internamente. -oc:tooltip.upgradeinventorycontroller=Este aprimoramento permite que robôs e drones tenham mais controle de como eles interagem com o inventário externo, e permite que robôs troquem sua ferramenta equipada com algum item do seu inventário. -oc:tooltip.upgrademf=Permite que adaptadores acessem blocos não adjacentes. -oc:tooltip.upgrademf.Linked=§fConexão estabelecida§7 -oc:tooltip.upgrademf.Unlinked=§fSem conexão§7 -oc:tooltip.upgradeleash=Permite que alguns dispostivos, como drones, coloquem animais em coleiras. MUITOSSSS ANIMAIIIIIIss. -oc:tooltip.upgradenavigation=Pode ser usado para determinar a posição e orientação de um dispositivo. A posição é relativa ao centro do mapa que foi usado para construir este aprimoramento. -oc:tooltip.upgradepiston=Este aprimoramento tem um movimento agressivo. Permite mexer blocos, como se estivesse usando um pistão. Isto §lnão§7 move entidades. -oc:tooltip.upgradesign=Permite ler e escrever em placas de texto. -oc:tooltip.upgradesolargenerator=Pode ser usado para gerar energia solar em movimento. Requer uma linha de visão limpa do céu acima do dispositivo. Gera energia em %s%% da velocidade de um Motor Stirling. -oc:tooltip.upgradetank=Este aprimoramento provê um armazenamento de tanque ou fluidos para robôs e drones. Sem um destes, ele não será capaz de armazenar fluidos internamente. -oc:tooltip.upgradetankcontroller=Este aprimoramento permite que robôs e drones tenham mais controle de como eles interagem com tanques externos, e permite que ele transfira fluidos para os tanques e dos tanques. -oc:tooltip.upgradetractorbeam=Equipa um dispositivo com uma tecnologia extremamente avançada, codenome "Imã". Permite que dispositivos capturem blocos com o raio de 3 blocos de sua localização. -oc:tooltip.upgradetrading=Permite que robôs e drones façam trocas com Aldeões. -oc:tooltip.waypoint=Provê um ponto de referência para os dispositvos com um aprimoramento de navegação. -oc:tooltip.wirelessnetworkcard=Permite enviar mensagens de rede além do meio normal. Você pode ajustar a §fforça do sinal§7 para controlar o quão longe as mensagens vão. Altos níveis de força de sinal resulta em alto consumo de energia. -oc:tooltip.worldsensorcard=Permite ler informações sobre o mundo, como gravidade e/ou se tem uma atmosfera respirável. Use os resultados por sua conta e risco. O fabricando não se responsabiliza por danos corporais ou materias por decisões causadas sobre as saídas dos cartões. Nós temos advogados. E dinheiro. Então nem tente. -oc:tooltip.wrench=Um híbrido entre uma Chave de fenda e uma Chave de boca, esta ferramenta é fácil de usar, mas díficil de dominar. - -#Achievements -achievement.oc.adapter=Ai que delicia cara. -achievement.oc.adapter.desc=Interagiu com blocos de outros mods e também do Minecraft vanilla! -achievement.oc.assembler=Explêndido -achievement.oc.assembler.desc=Hora de dominar o mundo! -achievement.oc.cable=Não é um Fio Sujo -achievement.oc.cable.desc=Com a tecnologia patenteada de anti-espaguete. -achievement.oc.capacitor=Baterias inclusas -achievement.oc.capacitor.desc=Você não pode parar isso. -achievement.oc.card=Aceitamos Cartões -achievement.oc.card.desc=Para sua conveniência. Sem segundas intenções, prometo. -achievement.oc.case=Em Caso de Problemas -achievement.oc.case.desc=Porque torres quadradas são as melhores. -achievement.oc.charger=Tá bom, vamo lá -achievement.oc.charger.desc=Carrreeegaaaan- poxa, esqueci do sinal de redstone de novo. -achievement.oc.chip=Todas as Pequenas Coisas -achievement.oc.chip.desc=Porque tubos a vácuo são coisa do passado. -achievement.oc.cpu=Overclocked -achievement.oc.cpu.desc=Hora de fazer uso destes ciclos computacionais. -achievement.oc.disassembler=Vamo quebra tudo! -achievement.oc.disassembler.desc=Caso suas ideias brilhantes não sejam tão brilhantes assim. -achievement.oc.diskDrive=Roda a Roda. -achievement.oc.diskDrive.desc=Capacidade inferior mas um som lindíssimo. -achievement.oc.drone=Voando alto. -achievement.oc.drone.desc=Mantenha a calma e jogue-o para fora do planeta. -achievement.oc.eeprom=Só pode ter um -achievement.oc.eeprom.desc=Por computador, claro. Para manter a ordem da inicialização, entendeu? -achievement.oc.floppy=Um ri- disco -achievement.oc.floppy.desc=Velho, mas ainda funciona. -achievement.oc.geolyzer=Pra dentro da Terra -achievement.oc.geolyzer.desc=Têm qualidades extraordinárias. -achievement.oc.graphicsCard=Ultima Geração -achievement.oc.graphicsCard.desc=Assim pode ser ... ann... rendereziado. Ah sim sim. -achievement.oc.hdd=HDD Melhor que HD -achievement.oc.hdd.desc=Não espere, não é isso que significa. Bom, você entendeu... -achievement.oc.hologram=Próxima Dimensão -achievement.oc.hologram.desc=Porque 2D é chato. Ou não é? -achievement.oc.keyboard=PegadorDeSujeira3000 -achievement.oc.keyboard.desc=É altamente recomendável resistir o impulso de girar eles no ar. -achievement.oc.microcontroller=Irmanzinha -achievement.oc.microcontroller.desc=O irmãozinho do computador. -achievement.oc.motionSensor=Mexe ae que quero vê -achievement.oc.motionSensor.desc=Igual a Steve Swagger. -achievement.oc.networkCard=Agora Estamos Falando! -achievement.oc.networkCard.desc=Mantenha contato com esses parentes distantes. -achievement.oc.openOS=Buti -achievement.oc.openOS.desc=Um SO para - espere, já usei essa antes? Droga. -achievement.oc.powerDistributor=Compartilhar é Amar -achievement.oc.powerDistributor.desc=Quando você precisa de ajuda para equilibrar toda essa energia. -achievement.oc.rack=Mas que potência -achievement.oc.rack.desc=Sim, os racks de servidores são potentes. -achievement.oc.raid=LFG -achievement.oc.raid.desc=Heroíco valeuflws. -achievement.oc.ram=Random Access Memories (Memórias de Acesso Aleatório) -achievement.oc.ram.desc=Parabéns, Você está fazendo isso certo. -achievement.oc.redstoneCard=Con... tato -achievement.oc.redstoneCard.desc=Hora de ser análogo. -achievement.oc.redstoneIO=Hello from the outside... -achievement.oc.redstoneIO.desc=Levando os sinais de redstone para onde quiser. -achievement.oc.robot=Bip Bip -achievement.oc.robot.desc=EXTERMINAR! -achievement.oc.screen=Tentou desligar e ligar de novo? -achievement.oc.screen.desc=Não, de verdade. Um pulso de redstone pode alternar o monitor entre ligado e desligado. -achievement.oc.server=Dedicado -achievement.oc.server.desc=Servidores na nuvem, aqui vamos nós. -achievement.oc.switch=Topologia Complexa -achievement.oc.switch.desc=Evite embalagens baratas devido a possibilidade de pacotes perdidos. -achievement.oc.tablet=Não Engula -achievement.oc.tablet.desc=Mantenha longe do alcance das crianças para evitar cobranças exageradas no seu cartão de crédito. -achievement.oc.transistor=Onipresente -achievement.oc.transistor.desc=Crie um Transistor para começar. -achievement.oc.wirelessNetworkCard=Sinais -achievement.oc.wirelessNetworkCard.desc=Hora de ir onde nenhum pacote foi antes. - -# Death messages. Note that the number of entries here must match the number -# set in the actual damage source in code. -death.attack.oc.nanomachinesOverload.1=%s foi muito ganancioso. -death.attack.oc.nanomachinesOverload.2=%s teve um ataque de nervos. -death.attack.oc.nanomachinesOverload.3=As nanomáquinas de %s estão fora de controle. -death.attack.oc.nanomachinesHungry.1=%s foi comido por nanomáquinas. -death.attack.oc.nanomachinesHungry.2=%s não alimentou suas nanomáquinas. -death.attack.oc.nanomachinesHungry.3=%s foi digerido. - -# NEI Integration -nei.options.inventory.oredict=Mostre nomes do OreDictionary -nei.options.inventory.oredict.true=Sim -nei.options.inventory.oredict.false=Não -nei.usage.oc.Manual=Open Manual - -# Waila Integration -option.oc.address=Endereço -option.oc.componentName=Nome do Componente -option.oc.energy=Energia diff --git a/src/main/resources/assets/opencomputers/lang/pt_PT.lang b/src/main/resources/assets/opencomputers/lang/pt_PT.lang deleted file mode 100644 index 23e0772fe6..0000000000 --- a/src/main/resources/assets/opencomputers/lang/pt_PT.lang +++ /dev/null @@ -1,137 +0,0 @@ -# This is the portuguese lang file, adapted from the english master file. -# -# CHANGES: -# LordFokas (6-JAN-2014): first translation from en_US to pt_PT. -# It's not perfect, but it's hard to translate, especially because -# given I'm a Computer Science Engineering student, I tend to mix in -# technical english words. I suggest someone less involved with CSE to -# try and revise my translation. -# -######################################################################### - - -# Blocks -tile.oc.adapter.name=Adaptador -tile.oc.cable.name=Cabo -tile.oc.capacitor.name=Condensador -tile.oc.case1.name=Caixa Básica -tile.oc.case2.name=Caixa Avançada -tile.oc.case3.name=Caixa Superior -tile.oc.charger.name=Carregador -tile.oc.diskdrive.name=Drive de Disquetes -tile.oc.keyboard.name=Teclado -tile.oc.powerconverter.name=Conversor de Energia -tile.oc.powerdistributor.name=Distribuidor de Energia -tile.oc.redstone.name=E/S de Redstone -tile.oc.robot.name=Robô -tile.oc.robotafterimage.name=Robô -tile.oc.screen1.name=Ecrã Básico -tile.oc.screen2.name=Ecrã Avançado -tile.oc.screen3.name=Ecrã Superior -tile.oc.switch.name=Roteador - -# Items -item.oc.acid.name=Grogue -item.oc.alu.name=Unidade Aritmética e Lógica -item.oc.analyzer.name=Analizador -item.oc.arrowkeys.name=Setas -item.oc.buttongroup.name=Grupo de Botões -item.oc.cardbase.name=Placa Base -item.oc.circuitboard.name=Placa de Circuitos -item.oc.controlunit.name=Unidade de Controlo -item.oc.cpu.name=Processador -item.oc.cuttingwire.name=Arame de Corte -item.oc.disk.name=Disco -item.oc.floppydisk.name=Disquete -item.oc.graphicscard0.name=Placa Gráfica Básica -item.oc.graphicscard1.name=Placa Gráfica Avançada -item.oc.graphicscard2.name=Placa Gráfica Superior -item.oc.harddiskdrive.name=Disco Rígido -item.oc.ironnugget.name=Pepita de Ferro -item.oc.memory.name=Memória -item.oc.microchip0.name=Circuito Integrado Simples -item.oc.microchip1.name=Circuito Integrado Avançado -item.oc.microchip2.name=Circuito Integrado Superior -item.oc.networkcard.name=Placa de Rede -item.oc.numpad.name=Teclado Numérico -item.oc.printedcircuitboard.name=Placa de Circuitos Impressos -item.oc.rawcircuitboard.name=Placa de Circuitos Vazia -item.oc.redstonecard.name=Placa de Redstone -item.oc.transistor.name=Transístor -item.oc.upgradecrafting.name=Melhoramento: Fabrico -item.oc.upgradegenerator.name=Melhoramento: Gerador -item.oc.upgradenavigation.name=Melhoramento: Navegação -item.oc.upgradesign.name=Melhoramento: Escrita e Leitura de Placas -item.oc.upgradesolargenerator.name=Melhoramento: Gerador Solar -item.oc.wirelessnetworkcard0.name=Placa de Rede sem Fios -item.oc.WirelessNetworkCard1.name=Placa de Rede sem Fios - -# GUI -oc:gui.Analyzer.Address=§6Endereço§f: %s -oc:gui.Analyzer.ComponentName=§6Nome do Componente§f: %s -oc:gui.Analyzer.LastError=§6Último erro§f: %s -oc:gui.Analyzer.RobotName=§6Nome§f: %s -oc:gui.Analyzer.RobotOwner=§6Proprietário§f: %s -oc:gui.Analyzer.RobotXp=§6Experiência§f: %s -oc:gui.Analyzer.StoredEnergy=§6Energia Armazenada§f: %s -oc:gui.Analyzer.TotalEnergy=§6Total de Energia Armazenada§f: %s -oc:gui.Analyzer.Users=§6Utilizadores§f: %s -oc:gui.Robot.Power=Energia -oc:gui.Robot.TurnOff=Desligar -oc:gui.Robot.TurnOn=Ligar - -# Containers -oc:container.case=Computador -oc:container.charger=Carregador -oc:container.diskdrive=Drive de Disquetes -oc:container.switch=Roteador - -# Item / Block Tooltips -oc:tooltip.acid=Um líquido muito tóxico, geralmente apenas consumido por alguns piratas. Graças à sua natureza corrosiva é perfeito para gravar placas de circuitos. -oc:tooltip.adapter=Usado para controlar blocos que não sejam componentes, tais como blocos do Minecraft Vanilla ou de outros mods. -oc:tooltip.alu=Faz cálculos por ti. Talvez seja melhor assim. -oc:tooltip.analyzer=Usado para mostrar informação acerca de blocos, tais como o seu §fendereço§7 e §fnome de componente§7.[nl] também mostra o erro que fez o computador crashar caso este não se tenha desligado normalmente. -oc:tooltip.cable=Uma forma barata de conectar blocos. -oc:tooltip.capacitor=Armazena energia para ser usada mais tarde. Pode encher e esvaziar-se muito rapidamente. -oc:tooltip.cardbase=Como o nome indica, é o componente básico para construir placas de expansão. -oc:tooltip.case=A Caixa é o bloco básico para a construção de computadores e contém as §fplacas de expansão§7, §fRAM§7 e §fdiscos rígidos§7.[nl] Slots: §f%s§7 -oc:tooltip.charger=Transfere energia dos condensadores para robôs adjacentes. A taxa de transferência depende do §fsinal de redstone§7 aplicado, onde nenhum sinal significa não carregar, e o sinal máximo significa carregar à velocidade máxima. -oc:tooltip.circuitboard=Agora estamos a chegar a algum lado. Pode ser gravada para obter uma placa de circuitos impressos. -oc:tooltip.controlunit=Esta é a unidade que... controla... coisas. Precisas dela para montar um Processador. Portanto, sim, pode-se dizer que é importante. -oc:tooltip.cpu=Um componente essencial de qualquer computador. A frequencia é pouco fiável, mas o que é que esperas quando corre com um relógio de sol? -oc:tooltip.cuttingwire=Usado para cortar blocos de barro na forma de uma placa. Parte-se ao fim de um uso, o que faz dela a ferramenta menos eficiente de sempre. -oc:tooltip.disk=Um meio primitivo que pode ser usado para construir dispositivos de armazenamento persistente. -oc:tooltip.diskdrive.CC=Disquetes do ComputerCraft são §asuportadas§7. -oc:tooltip.diskdrive=Permite ler e escrever dados em Disquetes. -oc:tooltip.graphicscard=Usado para alterar o que é mostrado nos ecrãs.[nl] Resolução máxima: §f%sx%s§7[nl] Profundidade de cor máxima: §f%s§7[nl] Operações/ciclo: §f%s§7 -oc:tooltip.ironnugget=Uma pepita feita de ferro, por isso é que se chama Pepita de Ferro, duh... -oc:tooltip.keyboard=Pode ligar-se a um ecrã para permitir escrever através dele. -oc:tooltip.memory=Necessária para poder usar um computador. Quanta mais RAM tiveres, mais complexos são os programas que podes correr. -oc:tooltip.microchip=Um chip antes conhecido por Circuito Integrado. Não faço ideia como é que isto funciona com redstone, mas funciona. -oc:tooltip.networkcard=Permite a computadores distantes ligados por blocos (tais como Cabos) comunicar enviando mensagens entre eles. -oc:tooltip.powerconverter.BuildCraft=§fMJ de Buildcraft§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fEU de IndustrialCraft²§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fRF de Thermal Expansion§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fCoulombs de Resonant Engine§7: §a%s:%s§7 -oc:tooltip.powerconverter=Converte energia de outros mods para o tipo de energia usado internamente. Taxas de conversão: -oc:tooltip.powerdistributor=Distribui energia entre diferentes redes. É util para alimentar várias redes separadas através de uma fonte de energia partilhada. -oc:tooltip.printedcircuitboard=O componente básico de placas de expansão, memórias e afins. -oc:tooltip.rawcircuitboard=Pode ser endurecida em qualquer fornalha. -oc:tooltip.redstone=Permite receber e emitir sinais de redstone. Pode ser controlado por qualquer computador ao qual o bloco esteja conectado. Basicamente isto é uma placa de controlo de redstone. -oc:tooltip.redstonecard.RedLogic=§fRedLogic§7 é §asuportado§7. -oc:tooltip.redstonecard.RedNet=§fRedNet§7 é §asuportado§7. -oc:tooltip.redstonecard=Permite ao computador ou robô receber e emitir sinais de redstone. -oc:tooltip.robot=Ao contrário dos computadores, os robôs podem mover-se e interagir com o mundo como um jogado. No entanto, eles §onão§r§7 podem interagir com componentes externos! -# the underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fNível§7: §a%s§7. -oc:tooltip.robot_storedenergy=§fEnergia Armazenada§7: §a%s§7. -oc:tooltip.screen=Mostra texto, controlado por uma placa gráfica numa Caixa.[nl] Resolução máxima: §f%sx%s§7[nl] Profundidade de cor máxima: §f%s§7 -oc:tooltip.switch=Permite interligar redes diferentes. Apenas pacotes de rede serão passados, componentes não serão visiveis em redes vizinhas. Usa isto para separar várias redes e ao mesmo tempo permitir comunicação através de placas de rede, por exemplo. -oc:tooltip.toolong=Prime [§f%s§7] para uma descrição detalhada. -oc:tooltip.transistor=Um componente básico do hardware do computador. É um pouco retorcido, mas faz o seu trabalho. -oc:tooltip.upgradecrafting=Permite aos robôs usar a parte superior esquerda do seu inventório para fabricar objectos. Os itens têm de estar alinhados como numa mesa de fabrico. -oc:tooltip.upgradegenerator=Pode ser usado para gerar energia a partir de combustível. Queima itens para gerar energia ao longo do tempo, dependendo da energia que pode ser extraída de cada componente.[nl] §fEficiência§7: §a%s%%§7 -oc:tooltip.upgradenavigation=Pode ser usado para determinar a posição e orientação do robô. A posição é relativa ao centro do mapa usado para fabricar este melhoramento. -oc:tooltip.upgradesign=Permiter ler e escrever texto em Placas. -oc:tooltip.upgradesolargenerator=Pode ser usado para gerar energia a partir da luz solar. Requer exposição directa à luz solar. Gera energia a %s%% da velocidade de um motor a carvão. -oc:tooltip.wirelessnetworkcard=Permite trocar mensagens em redes com e sem fios. Certifica-te que defines a §fforça do sinal§7 ou nenhum pacote será enviado via redes sem fios! \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/lang/pt_br.json b/src/main/resources/assets/opencomputers/lang/pt_br.json new file mode 100644 index 0000000000..2fb67eae36 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/pt_br.json @@ -0,0 +1,465 @@ +{ + "tile.oc.accesspoint": "§cPonto de Acesso§7", + "tile.oc.adapter": "Adaptador", + "tile.oc.assembler": "Montador Eletrônico", + "tile.oc.cable": "Cabo", + "tile.oc.capacitor": "Capacitador", + "tile.oc.carpetedCapacitor": "Capacitador com Tapete", + "tile.oc.case1": "Gabinete (Nível 1)", + "tile.oc.case2": "Gabinete (Nível 2)", + "tile.oc.case3": "Gabinete (Nível 3)", + "tile.oc.casecreative": "Gabinete (Criativo)", + "tile.oc.chameliumblock": "Bloco Camaleão", + "tile.oc.charger": "Carregador", + "tile.oc.disassembler": "Desmontador", + "tile.oc.diskdrive": "Unidade de Disco", + "tile.oc.endstone": "Pedra do Fim", + "tile.oc.geolyzer": "Geonalizador", + "tile.oc.hologram1": "Projetor Holográfico (Nível 1)", + "tile.oc.hologram2": "Projetor Holográfico (Nível 2)", + "tile.oc.keyboard": "Teclado", + "tile.oc.microcontroller": "Microcontrolador", + "tile.oc.motionsensor": "Sensor de Movimento", + "tile.oc.netsplitter": "Divisor de Rede", + "tile.oc.powerconverter": "Conversor de Energia", + "tile.oc.powerdistributor": "Distribuidor de Energia", + "tile.oc.print": "Impressão 3D", + "tile.oc.printer": "Impressora 3D", + "tile.oc.raid": "Raid", + "tile.oc.redstone": " E/S de Redstone", + "tile.oc.relay": "Relé", + "tile.oc.robot": "Robô", + "tile.oc.robotafterimage": "Robô", + "tile.oc.screen1": "Monitor (Nível 1)", + "tile.oc.screen2": "Monitor (Nível 2)", + "tile.oc.screen3": "Monitor (Nível 3)", + "tile.oc.rack": "Rack", + "tile.oc.switch": "§cSwitch§7", + "tile.oc.transposer": "Transpositor", + "tile.oc.waypoint": "Ponto de Passagem", + "item.oc.abstractbuscard": "Placa de Barramento Abstrata", + "item.oc.acid": "Grogue", + "item.oc.alu": "Unidade Lógica Aritmética (ULA)", + "item.oc.analyzer": "Analizador", + "item.oc.apu0": "Unidade de Processamento Acelerado (UPA) (Nível 1)", + "item.oc.apu1": "Unidade de Processamento Acelerado (UPA) (Nível 2)", + "item.oc.apu2": "Unidade de Processamento Acelerado (UPA) (Criativo)", + "item.oc.arrowkeys": "Setas do Teclado", + "item.oc.buttongroup": "Grupo de Botões", + "item.oc.cardbase": "Base de Cartão", + "item.oc.chamelium": "Camaleão", + "item.oc.circuitboard": "Placa de Circuito", + "item.oc.componentbus0": "Componente de Barramento (Nível 1)", + "item.oc.componentbus1": "Componente de Barramento (Nível 2)", + "item.oc.componentbus2": "Componente de Barramento (Nível 3)", + "item.oc.componentbus3": "Componente de Barramento (Criativo)", + "item.oc.controlunit": "Unidade de Controle (UC)", + "item.oc.cpu0": "Unidade Central de Processamento (CPU) (Nível 1)", + "item.oc.cpu1": "Unidade Central de Processamento (CPU) (Nível 2)", + "item.oc.cpu2": "Unidade Central de Processamento (CPU) (Nível 3)", + "item.oc.cuttingwire": "Fio de Corte", + "item.oc.datacard0": "Cartão de Dados (Nível 1)", + "item.oc.datacard1": "Cartão de Dados (Nível 2)", + "item.oc.datacard2": "Cartão de Dados (Nível 3)", + "item.oc.debugcard": "Cartão de Depuração", + "item.oc.debugger": "Depurador de Rede", + "item.oc.diamondchip": "Chip de Diamante", + "item.oc.disk": "Prato do Disco", + "item.oc.diskdrivemountable": "Unidade de Disco", + "item.oc.drone": "Drone", + "item.oc.dronecase0": "Carcaça de Drone (Nível 1)", + "item.oc.dronecase1": "Carcaça de Drone (Nível 2)", + "item.oc.dronecase3": "Carcaça de Drone (Criativo)", + "item.oc.eeprom": "EEPROM", + "item.oc.floppydisk": "Disquete", + "item.oc.graphicscard0": "Placa de Vídeo (Nível 1)", + "item.oc.graphicscard1": "Placa de Vídeo (Nível 2)", + "item.oc.graphicscard2": "Placa de Vídeo (Nível 3)", + "item.oc.harddiskdrive0": "Disco Rígido (Nível 1)", + "item.oc.harddiskdrive1": "Disco Rígido (Nível 2)", + "item.oc.harddiskdrive2": "Disco Rígido (Nível 3)", + "item.oc.hoverboots": "Botas Voadoras", + "item.oc.inkcartridge": "Cartucho de Tinta", + "item.oc.inkcartridgeempty": "Cartucho de Tinta (Vazio)", + "item.oc.internetcard": "Cartão de Internet", + "item.oc.interweb": "Interweb", + "item.oc.ironnugget": "Pepita de Ferro", + "item.oc.linkedcard": "Cartão Vinculado", + "item.oc.manual": "Manual do OpenComputers", + "item.oc.memory0": "Memória (Nível 1)", + "item.oc.memory1": "Memória (Nível 1.5)", + "item.oc.memory2": "Memória (Nível 2)", + "item.oc.memory3": "Memória (Nível 2.5)", + "item.oc.memory4": "Memória (Nível 3)", + "item.oc.memory5": "Memória (Nível 3.5)", + "item.oc.microchip0": "Circuito Integrado (Nível 1)", + "item.oc.microchip1": "Circuito Integrado (Nível 2)", + "item.oc.microchip2": "Circuito Integrado (Nível 3)", + "item.oc.microcontrollercase0": "Carcaça do Microcontrolador (Nível 1)", + "item.oc.microcontrollercase1": "Carcaça do Microcontrolador (Nível 2)", + "item.oc.microcontrollercase3": "Carcaça do Microcontrolador (Criativo)", + "item.oc.nanomachines": "Nanomáquinas", + "item.oc.networkcard": "Cartão de Rede", + "item.oc.numpad": "Teclado Numérico", + "item.oc.present": "Uma coisinha...", + "item.oc.printedcircuitboard": "Placa de Circuito Impresso (PCB)", + "item.oc.rawcircuitboard": "Placa de Circuito Crua", + "item.oc.redstonecard0": "Cartão de Redstone (Nível 1)", + "item.oc.redstonecard1": "Cartão de Redstone (Nível 2)", + "item.oc.server0": "Servidor (Nível 1)", + "item.oc.server1": "Servidor (Nível 2)", + "item.oc.server2": "Servidor (Nível 3)", + "item.oc.server3": "Servidor (Criativo)", + "item.oc.tablet": "Tablet", + "item.oc.tabletcase0": "Carcaça de Tablet (Nível 1)", + "item.oc.tabletcase1": "Carcaça de Tablet (Nível 2)", + "item.oc.tabletcase3": "Carcaça de Tablet (Criativo)", + "item.oc.terminal": "Terminal Remoto", + "item.oc.terminalserver": "Servidor de Terminal", + "item.oc.texturepicker": "Selecionador de Textura", + "item.oc.transistor": "Transistor", + "item.oc.upgradeangel": "Aprimoramento Angelical", + "item.oc.upgradebattery0": "Aprimoramento de Bateria (Nível 1)", + "item.oc.upgradebattery1": "Aprimoramento de Bateria (Nível 2)", + "item.oc.upgradebattery2": "Aprimoramento de Bateria (Nível 3)", + "item.oc.upgradechunkloader": "Aprimoramento de Chunkloader", + "item.oc.upgradecontainercard0": "Contêiner de Cartão (Nível 1)", + "item.oc.upgradecontainercard1": "Contêiner de Cartão (Nível 2)", + "item.oc.upgradecontainercard2": "Contêiner de Cartão (Nível 3)", + "item.oc.upgradecontainerupgrade0": "Aprimoramento de Contêiner (Nível 1)", + "item.oc.upgradecontainerupgrade1": "Aprimoramento de Contêiner (Nível 2)", + "item.oc.upgradecontainerupgrade2": "Aprimoramento de Contêiner (Nível 3)", + "item.oc.upgradecrafting": "Aprimoramento de Construção", + "item.oc.upgradedatabase0": "Aprimoramento de Banco de Dados (Nível 1)", + "item.oc.upgradedatabase1": "Aprimoramento de Banco de Dados (Nível 2)", + "item.oc.upgradedatabase2": "Aprimoramento de Banco de Dados (Nível 3)", + "item.oc.upgradeexperience": "Aprimoramento de Experiência", + "item.oc.upgradegenerator": "Aprimoramento de Gerador", + "item.oc.upgradehover0": "Aprimoramento de Flutuação (Nível 1)", + "item.oc.upgradehover1": "Aprimoramento de Flutuação (Nível 2)", + "item.oc.upgradeinventory": "Aprimoramento de Inventário", + "item.oc.upgradeinventorycontroller": "Aprimoramento de Controlador de Inventário", + "item.oc.upgradeleash": "Aprimoramento de Correia", + "item.oc.upgradeMF": "MFU", + "item.oc.upgradenavigation": "Aprimoramento de Navegação", + "item.oc.upgradepiston": "Aprimoramento de Pistão", + "item.oc.upgradesign": "Aprimoramento de Sinal de E/S", + "item.oc.upgradesolargenerator": "Aprimoramento de Gerador Solar", + "item.oc.upgradetank": "Aprimoramento de Tanque", + "item.oc.upgradetankcontroller": "Aprimoramento de Controlador de Tanque", + "item.oc.upgradetractorbeam": "Aprimoramento de Raio Trator", + "item.oc.upgradetrading": "Aprimoramento de Troca", + "item.oc.wirelessnetworkcard0": "Cartão de Rede Sem Fio (Nível 1)", + "item.oc.wirelessnetworkcard1": "Cartão de Rede Sem Fio (Nível 2)", + "item.oc.worldsensorcard": "Cartão de Sensor de Mundo", + "item.oc.wrench": "Chave de fenda-boca", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.Drone": "Drone", + "oc:gui.Analyzer.Address": "§6Endereço§f: %s", + "oc:gui.Analyzer.AddressCopied": "Endereço copiado para a área de transferência.", + "oc:gui.Analyzer.ChargerSpeed": "§6Velocidade da carga§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Nome do componente§f: %s", + "oc:gui.Analyzer.Components": "§6Número de componentes conectados§f: %s", + "oc:gui.Analyzer.CopyToClipboard": "Clique para copiar para a área de transferência.", + "oc:gui.Analyzer.LastError": "§6Último erro§f: %s", + "oc:gui.Analyzer.RobotName": "§6Nome§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Dono§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Experiência§f: %s (Nível %s)", + "oc:gui.Analyzer.StoredEnergy": "§6Energia armazenada§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Total de energia armazenada§f: %s", + "oc:gui.Analyzer.Users": "§6Usuários§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6Força do sinal§f: %s", + "oc:gui.Assembler.Collect": "Saída do coletador", + "oc:gui.Assembler.Complexity": "Complexidade: %s/%s", + "oc:gui.Assembler.InsertCase": "Insira uma parte base", + "oc:gui.Assembler.InsertCPU": "Insira uma CPU", + "oc:gui.Assembler.InsertRAM": "Insira alguma RAM", + "oc:gui.Assembler.Progress": "Progresso: %s%% (%s)", + "oc:gui.Assembler.Run": "Montar", + "oc:gui.Assembler.Warning.BIOS": "BIOS", + "oc:gui.Assembler.Warning.GraphicsCard": "Placa de Vídeo", + "oc:gui.Assembler.Warning.Inventory": "Aprimoramento de Inventário", + "oc:gui.Assembler.Warning.Keyboard": "Teclado", + "oc:gui.Assembler.Warning.OS": "Mídia Inicializável", + "oc:gui.Assembler.Warning.Screen": "Monitor", + "oc:gui.Assembler.Warnings": "§eAtenção§7: Componentes recomendados ausentes.", + "oc:gui.Chat.NewVersion": "Uma nova versão está disponível: %s", + "oc:gui.Chat.TextureName": "§7Nome da textura é §a%s§f.", + "oc:gui.Chat.WarningClassTransformer": "Houve um erro §cerros§f ao rodar o 'class transformer'. Por favor relate isso, junto com o seu arquivo de log (completo!) FML §alatest.log§f/§afml-server-latest.log§f , obrigado!", + "oc:gui.Chat.WarningFingerprint": "§cATENÇÃO§f - impressão digital não reconhecida! Experado '§a%s§f' mas recebido '§e%s§f'. A não ser que você seja um desenvolvedor e esteja rodando uma versão desofuscada, é §lextremamente§f recomendável que baixe novamente o OpenComputers, por que o JAR que está usando talvez esteja adulterado.", + "oc:gui.Chat.WarningLink": "Não foi possível abrir o atalho: %s", + "oc:gui.Chat.WarningLuaFallback": "Bibliotecas nativas do Lua não disponíveis, computadores não serão capazes de persistir seus estados. Eles reinicializarão quando chunks descarregarem.", + "oc:gui.Chat.WarningProjectRed": "Você está usando uma versão do Project: Red que é incompativel com OpenComputers. Tente atualizar sua versão do Project: Red.", + "oc:gui.Chat.WarningRecipes": "Houve erros ao carregar uma ou mais receitas. Alguns itens não poderão ser construídos. Verifique seu arquivo de log para mais informações.", + "oc:gui.Drive.Managed": "Gerenciado", + "oc:gui.Drive.Unmanaged": "Não Gerenciado", + "oc:gui.Drive.ReadOnlyLock": "Bloqueado", + "oc:gui.Drive.ReadOnlyLockWarning": "§Somente leitura§r. Isso não pode ser removido, exceto quando o disco é formatado.", + "oc:gui.Drive.Warning": "§lAtençaõ§r: mudança de modos resultará em perca de todos os dados do disco!", + "oc:gui.Error.ComponentOverflow": "Muitos componentes conectados ao computador.", + "oc:gui.Error.InternalError": "Erro interno, por favor veja o arquivo de log. Isto é provavelmente um erro.", + "oc:gui.Error.NoCPU": "Não há CPU instalada no computador.", + "oc:gui.Error.NoEnergy": "Energia insuficiente.", + "oc:gui.Error.NoRAM": "Não há RAM instalada no computador.", + "oc:gui.Error.OutOfMemory": "Sem memória.", + "oc:gui.Manual.Blocks": "Blocos do OpenComputers", + "oc:gui.Manual.Home": "Início", + "oc:gui.Manual.Items": "Itens do OpenComputers", + "oc:gui.Manual.Warning.BlockMissing": "Bloco indisponível.", + "oc:gui.Manual.Warning.ImageMissing": "Imagem não encontrada.", + "oc:gui.Manual.Warning.ItemMissing": "Item indisponível.", + "oc:gui.Manual.Warning.OreDictMissing": "Entrada no dicionário de minérios indisponível.", + "oc:gui.Raid.Warning": "§4Adicionar um disco o formata.\nRemover um disco limpa a raid.", + "oc:gui.Robot.Power": "Energia", + "oc:gui.Robot.TurnOff": "Desligar", + "oc:gui.Robot.TurnOn": "Ligar\n§7Use um Analizador para verficar problemas.§r", + "oc:gui.Rack.Back": "Voltar", + "oc:gui.Rack.Bottom": "Baixo", + "oc:gui.Rack.Left": "Esquerda", + "oc:gui.Rack.None": "Nenhum", + "oc:gui.Rack.Right": "Direita", + "oc:gui.Rack.Enabled": "Habilitado", + "oc:gui.Rack.Disabled": "Disabilitado", + "oc:gui.Rack.RelayModeTooltip": "Modo de relé", + "oc:gui.Rack.Top": "Cima", + "oc:gui.Switch.PacketsPerCycle": "Pacotes / ciclo", + "oc:gui.Switch.QueueSize": "Tamanho da fila", + "oc:gui.Switch.TransferRate": "Taxa do ciclo", + "oc:gui.Terminal.InvalidKey": "Chave inválida, provavelmente outro terminal foi conectado ao servidor.", + "oc:gui.Terminal.OutOfRange": "Sem sinal.", + "oc:container.accesspoint": "Ponto de Acesso", + "oc:container.adapter": "Adaptador", + "oc:container.case": "Computador", + "oc:container.charger": "Carregador", + "oc:container.disassembler": "Desmontador", + "oc:container.diskdrive": "Unidade de disco", + "oc:container.printer": "Impressora", + "oc:container.raid": "Raid", + "oc:container.relay": "Relé", + "oc:container.server": "Servidor", + "oc:container.rack": "Rack", + "oc:container.switch": "Switch", + "oc:container.tabletwrapper": "Tablet", + "key.opencomputers.clipboardPaste": "Colar da área de transferência", + "key.opencomputers.materialCosts": "Mostrar custo dos materiais", + "oc:tooltip.accesspoint": "Atua como um Switch, mas adicionalmente recebe pacotes sem fio e retransmite pacotes com fio sem fio.", + "oc:tooltip.abstractbuscard": "Permite interagir com o barramento abstrato de §fStargateTech 2§7 enviando e recebendo pacotes LIP.", + "oc:tooltip.acid": "Um pseudo-liquido altamente tóxico, usualmente consumidos por alguns piratas (ihic!). Também, todavia, pode ser útil de outros modos.", + "oc:tooltip.adapter": "Usado para controlar blocos que não são componentes, tal como blocos vanillas ou de outros mods.", + "oc:tooltip.alu": "Adiciona números que você não têm. Bem melhor assim.", + "oc:tooltip.analyzer": "Usado para mostrar informações sobre os blocos, tal como seu §fendereço§7 e §fnome do componente§7.\nTambém mostra o erro que causou um computador travar se não foi desligado normalmente.", + "oc:tooltip.apu": "Isso é um CPU com um GPU integrado (ou IGP), quando você apenas precisa deste slot de placa .\nComponentes Suportados: §f%s§7\nResolução mãxima: §f%sx%s§7\nDensidade de cores máxima: §f%s§7\nOperações/tick: §f%s§7", + "oc:tooltip.assembler": "Permite construir robôs e outros dispositivos com várias partes de computador.", + "oc:tooltip.cable": "Uma maneira barata de conectar os blocos.", + "oc:tooltip.capacitor": "Armazena energia para usar mais tarde. Pode ser enchido e esvaziado rapidamente.", + "oc:tooltip.cardbase": "Como o nome diz, este é o bloco de construção básico para os cartões de expansão.", + "oc:tooltip.carpetedcapacitor": "Armazena energia para uso posterior. Pode ser carregado e descarregado rapidamente. Carrega quando uma ovelha ou jaguatirica anda sobre o mesmo.", + "oc:tooltip.case": "O gabinete é o bloco básico para computadores e guarda os §fcartões de extensão§7, §fRAM§7 e §fdiscos rígidos§7.\nSlots: §f%s§7", + "oc:tooltip.chamelium": "Matéria prima para as imressões 3D. Não ingerir: talvez leve a cegueira e um lapso temporário de presença.", + "oc:tooltip.chameliumblock": "Agradável e Limpo. Usado para formas coloridas nas impressões 3D, ou para simplesmente ter, um bloco colorido para decorar sua linda e chamativa base.", + "oc:tooltip.charger": "Transfere energia dos capacitores para robôs e drones adjacentes. A taxa de energia depende do §fsinal de redstone§7 vindo, onde sem sinal não carrega os dispositivos, e quanto mais forte o sinal maior será a velocidade de carregamento. Pode ser usado também para carregar tablets e unidades de disco de acesso em tablets.", + "oc:tooltip.circuitboard": "Agora estamos chegando em algum lugar. Pode ser cozido para obter uma placa de circuito impresso.", + "oc:tooltip.controlunit": "Está é a unidade que... controla... coisas. Você precisa disso para construir a CPU. Então é tipo, totalmente importante.", + "oc:tooltip.componentbus": "Está expansão permite aos servidores comunicarem com mais componentes ao mesmo tempo, similar como os CPUs fazem.\nComponentes Suportados: §f%s§7", + "oc:tooltip.cpu": "Um componente essencial para todos os computadores. O clock (relógio/taxa do processamento) é um tanto quanto que duvidoso, mas o que você espera se ele roda num relógio de sol de bolso?\nComponentes Suportados: §f%s§7", + "oc:tooltip.cpu.Architecture": "Arquitetura: §f%s§7", + "oc:tooltip.cuttingwire": "Usado para cortar blocos de argila em formato de placas de circuito. Quebra quando usa, o que provavelmente é a pior ferramenta de todas.", + "oc:tooltip.datacard0": "Provê um conjuto de algoritmos tal como hash e desinflar/inflar.", + "oc:tooltip.datacard1": "Provê um conjuto de algoritmos tal como hash, encriptação AES e desinflar/inflar.", + "oc:tooltip.datacard2": "Provê um conjuto de algoritmos tal como hash, encriptação AES, criptografia de curva elíptica e desinflar/inflar.", + "oc:tooltip.debugcard": "Item do modo criativo, permite manipular o mundo para fazer testes facieis. Use por sua conta e risco.", + "oc:tooltip.debugger": "Pode ser usado para depurar informações na grade de rede interna do OC. Somente use se for instruído por um desenvolvedor.", + "oc:tooltip.diamondchip": "Um pedacinho de um diamante uma vez impecável. Ele nunca será o mesmo de novo.", + "oc:tooltip.disassembler": "Separa os itens em seus componentes originais. §lAtenção§7: o item retornado tem uma chance de %s%% de quebrar no processo!", + "oc:tooltip.disk": "Uma mídia primitiva que pode ser usada para construir dispositvos de armazenamentos contínuos.", + "oc:tooltip.diskdrive.CC": "Disquetes do ComputerCraft são §asuportados§7.", + "oc:tooltip.diskdrive": "Permite escrever e ler disquetes. Pode ser instalado em robôs para permitir inserir disquetes mais tarde.", + "oc:tooltip.diskdrivemountable": "Provê a mesma funcionalidade de uma unidade de disco normal, mas só pode ser instalado em um rack.", + "oc:tooltip.diskusage": "Uso de disco: %s/%s Byte", + "oc:tooltip.disklocked": "Bloqueado por: %s", + "oc:tooltip.diskmodemanaged": "Modo: Gerenciado", + "oc:tooltip.diskmodeunmanaged": "Modo: Não gerenciado", + "oc:tooltip.drone": "Drones são leves, com reconhecimento rápido de unidades com espaço interno limitado.", + "oc:tooltip.dronecase": "Está carcaça é usada para montar drones no montador. Ele tem um espaço para uma pequena quantidade de componentes e provê levitação com a pedra do fim.", + "oc:tooltip.eeprom": "Pequeno armazenamento programável que contem a BIOS dos computadores usado para iniciá-los.", + "oc:tooltip.fakeendstone": "Quase igual a coisa real, emula até mesmo sua levitação!", + "oc:tooltip.geolyzer": "Permite escanear a dureza da área ao redor de blocos sólidos. Essa informação pode ser útil para geração de hologramas de área ou para detectar minérios.", + "oc:tooltip.graphicscard": "Usado para mudar o que é mostrado nos monitores.\nMáxima resolução: §f%sx%s§7\nMáxima profundidade de cores: §f%s§7\nOperações/tick: §f%s§7", + "oc:tooltip.hoverboots": "Pule alto, caia devagar, caminhe melhor. Isso e mais, com as mais novas e patenteadas Botas Voadoras (TM).", + "oc:tooltip.inkcartridge": "Usado para carregar tinta nas impressoras 3D. Por razões misteriosas ele não tem que permanecer na impressora.", + "oc:tooltip.inkcartridgeempty": "Este cartucho de tinta foi usado até secar. Recarregue isso usando corantes. Ou jogue-o fora. Veja minha cara de preocupado -.-.", + "oc:tooltip.internetcard": "Este cartão faz requisições HTTP usa protocolos TCP reais.", + "oc:tooltip.interweb": "Parabéns, você ganhou um (1) interweb. Você pode conectar a isso usando um Cartão de Internet. Cuidado: não alimente os trolls.", + "oc:tooltip.ironnugget": "Uma pepita feita de ferro, por isso é chamado de Pepita de Ferro, darrr...", + "oc:tooltip.keyboard": "Pode ser anexados aos monitores para permitir digitar neles.", + "oc:tooltip.hologram0": "Uma exibição volumétrica que pode ser controlado por computadores para exibir estruturas de voxel arbitrárias.\nResolução: §f48x32x48§7\nEscala máxima: §f3x§7\nProfundidade de cores: §fMonocromatico§7", + "oc:tooltip.hologram1": "Uma exibição volumétrica que pode ser controlado por computadores para exibir estruturas de voxel arbitrárias.\nResolução: §f48x32x48§7\nEscala máxima: §f4x§7\nProfundidade de cores: §fTricolor§7", + "oc:tooltip.linkedcard": "Eles são construidos em pares, e só pode comunicar-se com seu par. Entretanto, eles podem se comunicar em qualquer distância, e também cruzar dimensões. A energia requerida para enviar a mensagem é altíssima.", + "oc:tooltip.linkedcard_channel": "§8Canal: %s§7", + "oc:tooltip.manual": "Toda informaçâo que você provalvemente precisará do OpenComputers. E mais. Por um preço inacreditável de... §opor favor pressiona R para continuar§7.", + "oc:tooltip.materialcosts": "Segure [§f%s§7] para custos do material.", + "oc:tooltip.materials": "Materiais:", + "oc:tooltip.memory": "Requerida para fazer os computadores funcionarem. Quanto mais tiver, mais complexos podem ser os programas.", + "oc:tooltip.microchip": "Um chip conhecido formalmente como Circuito Integrado. Eu não tenho ideia porque isso funciona com redstone, mas funciona.", + "oc:tooltip.microcontroller": "Microcontroladores são mini computadores. Eles são usadas para cuidar de tarefas específicas, rodando um único programa que é provido pela EEPROM consruida dentro dele.\n§cNão pode conectar com componentes externos.§7", + "oc:tooltip.microcontrollercase": "Componente básico para construir microcontroladores. Coloque-o em um montador para adicionar novos componentes e montar um microcontrolador.", + "oc:tooltip.motionsensor": "Pode detectar movimento de formas de vidas próximas. Requer visão direta.", + "oc:tooltip.nanomachines": "Unidade de controle e um grupo de nanomáquinas pra ingerir, se você tiver coragem.", + "oc:tooltip.networkcard": "Permite que computadores distantes conectem por outros blocos (como cabos) para comunicar-se enviando mensagens um para o outro.", + "oc:tooltip.poweracceptor": "Velocidade da conversão de energia: §f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§fBuildCraft MJ§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§fCarregamento do Factorization§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fIndustrialCraft² EU§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§fMekanism Joules§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fThermal Expansion RF§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fResonant Engine Coulombs§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Converte energia de outros mods para o tipo de energia interna. Taxa de conversão:", + "oc:tooltip.powerdistributor": "Distribui energia por meio de diferentes redes. Isto é útil para compartilhar fluxo de energia de seu sistema para outro conversor em diferentes sub-redes que podem manter separados.", + "oc:tooltip.present": "... para seus problemas. Abra este presente para ter uma chance de receber §kum grande tesouro§7!\n§8Construa itens do OpenComputers para ter uma chance de receber presente.§7", + "oc:tooltip.print.BeaconBase": "§8Funciona como uma base do sinalizador.", + "oc:tooltip.print.LightValue": "§8Luz emitida: %s.", + "oc:tooltip.print.RedstoneLevel": "§8Saída da Redstone: %s.", + "oc:tooltip.printedcircuitboard": "O bloco de construção básico para cartões de expansão, memória e outros.", + "oc:tooltip.printer": "Permite imprimir blocos com forma definida pelo usuário usando o Camaleão (nome lindo?) e Cartucho de Tinta. Deve ser configurado usando um computador. Deixe longe do alcance das crianças. Porque sim.", + "oc:tooltip.raid": "Permite cobinar três discos rigídos em um único grande arquivo de sistema que pode ser usado por todos os computadores conectados.", + "oc:tooltip.rawcircuitboard": "Pode ser endurecido em qualquer fornalha compátivel.", + "oc:tooltip.redstone": "Permite ler e emitir sinais de redstone ao redor do bloco. Pode ser controlado por qualquer computador que o bloco estiver conectado. Isto é básicamente um cartão de redstone externo.", + "oc:tooltip.redstonecard.ProjectRed": "§fProjectRed§7 é §asuportado§7.", + "oc:tooltip.redstonecard.RedLogic": "§fRedLogic§7 é §asuportado§7.", + "oc:tooltip.redstonecard.RedNet": "§fRedNet§7 é §asuportado§7.", + "oc:tooltip.redstonecard.WirelessCBE": "§fWireless Redstone (ChickenBones)§7 é §asuportado§7.", + "oc:tooltip.redstonecard.WirelessSV": "§fWireless Redstone (SlimeVoid)§7 é §asuportado§7.", + "oc:tooltip.redstonecard": "Permite ler e emitir sinais de redstone ao redor do robô computadorizado.", + "oc:tooltip.relay": "Permite conectar diversas redes uma com a outra. Somente mensagens de rede serão passadas, componentes não serão vísiveis através disto. Use para separar redes e continuar permitindo comunicação usando Cartões de Rede, por exemplo.", + "oc:tooltip.robot": "Diferente de computadores, robôs podem mover-se por ai e interagir com o mundo parecido com o que um jogador faz.\n§cNão pode conectar-se com componentes externos.§7", + "oc:tooltip.robot_level": "§fNível§7: §a%s§7", + "oc:tooltip.robot_storedenergy": "§fEnergia armazenada§7: §a%s§7", + "oc:tooltip.screen": "Mostra texto, controlado por uma placa de vídeo em um Gabinete.\nResolução máxima: §f%sx%s§7\nDensidade máxima: §f%s§7", + "oc:tooltip.server": "Isto é um servidor: existem muitos como este, mas este pode ser aprimorado com componentes como um gabinete pode ser. Ele pode ser ligado inserindo-o em um rack de servidor.", + "oc:tooltip.server.Components": "Componentes instalados:", + "oc:tooltip.rack": "Permite a instalação de até quatro servidores ou outros montáveis.", + "oc:tooltip.switch": "Permite conectar várias redes uma com a outra. Somente mensagens de rede serão transmitidas, componentes não serão vísiveis. Use-o para separar redes permitindo comunicação usando Cartões de Rede, por exemplo.", + "oc:tooltip.tablet": "Um tablet, para usar Lua de maneira portátil. Pode ser forçado a desligar se abaixando e ativando-o.", + "oc:tooltip.tabletcase": "Carcaça básica para tablets. Coloque-o no montador para adicionar componentes e criar um tablet.", + "oc:tooltip.terminal": "Permite controlar um servidor remotamente, enquanto estiver no seu alcance. Atua como monitor e teclados portateis. Shift + Botão Direito em um servidor em um rack para vincular um terminal.", + "oc:tooltip.terminalserver": "Backend para que Terminais remotos possam ser conectados para prover controle remoto. Contém um monitor virtual e um teclado.", + "oc:tooltip.texturepicker": "Esta ferramente mostra uma string descrevendo uma superfície de bloco, para usar na impressora 3D e definir formas. Não são nomes de texturas, nana nina não.", + "oc:tooltip.tier": "§8Nível %s", + "oc:tooltip.netsplitter": "Atua como um conector dinâmico. Conectividade de cada lado pode ser mudada batendo-a com uma chave. Conectividade de todos os lados podem ser invertidas aplicando um sinal de redstone.", + "oc:tooltip.toolong": "Segure [§f%s§7] para uma dica detalhada.", + "oc:tooltip.transistor": "Um elemento básico para outras partes de computador. É um pouco torto, mas faz seu trabalho.", + "oc:tooltip.transposer": "Permite transferir automaticamente itens e fluidos entre inventários adjacentes e recipientes de fluidos.", + "oc:tooltip.upgradeangel": "Permite que robôs coloquem blocos no ar, mesmo sem um ponto de apoio.", + "oc:tooltip.upgradebattery": "Aumenta a quantidade de energia que o dispositivo pode armazenar, permitindo que trabalhe mais tempo sem precisa recarregar.\nCapacidade: §f%s§7", + "oc:tooltip.upgradechunkloader": "Se um robô move-se em uma floresta e ninguém é capaz de ver ele, ele está se mexendo ou não? Este aprimoramento faz ter certeza que sim. Isto mantêm um chunk em que um dispositvo está carregado, mas consome energia continuamente enquanto ativo.", + "oc:tooltip.upgradecontainercard": "Este aprimoramento de contêiner permite dinamicamente instalar e remover um cartão de um dispositivo montado.\nNível máximo: §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "Este aprimoramento de contêiner permite dinamicamente instalar e remover outro aprimoramento de um dispositivo montado.\nNível máximo: §f%s§7", + "oc:tooltip.upgradecrafting": "Permite que robôs usem o canto superior esquerdo de seu inventário para construir objetos. Os itens devem estar posicionados como se estivessem numa mesa de trabalho.", + "oc:tooltip.upgradedatabase": "Este aprimoramento permite armazenar informação de pilha de itens para ser usado por outros componentes.\nEntradas suportadas: §f%s§7", + "oc:tooltip.upgradeexperience": "Este aprimoramento permite que robôs acumulem experiência efetuando diversas operações. Quanto mais experiência estiver, mais energia pode armazenar, mais rápido pode cortar blocos e mais efeciente ele usa as ferramentas.", + "oc:tooltip.upgradegenerator": "Pode ser usado para gerar combustível em movimento. Queima itens para gerar energia o tempo todo, baseado em seus valores de combustível.\n§fEfeciencia§7: §a%s%%§7", + "oc:tooltip.upgradehover": "Este aprimoramento permite que robôs voem acima do solo sem precisar escalar paredes.\nAltura máxima: §f%s§7", + "oc:tooltip.upgradeinventory": "Este aprimoramento provê espaço no inventário para robôs ou drones. Sem um destes, eles não serão capazes de armazenar itens internamente.", + "oc:tooltip.upgradeinventorycontroller": "Este aprimoramento permite que robôs e drones tenham mais controle de como eles interagem com o inventário externo, e permite que robôs troquem sua ferramenta equipada com algum item do seu inventário.", + "oc:tooltip.upgrademf": "Permite que adaptadores acessem blocos não adjacentes.", + "oc:tooltip.upgrademf.Linked": "§fConexão estabelecida§7", + "oc:tooltip.upgrademf.Unlinked": "§fSem conexão§7", + "oc:tooltip.upgradeleash": "Permite que alguns dispostivos, como drones, coloquem animais em coleiras. MUITOSSSS ANIMAIIIIIIss.", + "oc:tooltip.upgradenavigation": "Pode ser usado para determinar a posição e orientação de um dispositivo. A posição é relativa ao centro do mapa que foi usado para construir este aprimoramento.", + "oc:tooltip.upgradepiston": "Este aprimoramento tem um movimento agressivo. Permite mexer blocos, como se estivesse usando um pistão. Isto §lnão§7 move entidades.", + "oc:tooltip.upgradesign": "Permite ler e escrever em placas de texto.", + "oc:tooltip.upgradesolargenerator": "Pode ser usado para gerar energia solar em movimento. Requer uma linha de visão limpa do céu acima do dispositivo. Gera energia em %s%% da velocidade de um Motor Stirling.", + "oc:tooltip.upgradetank": "Este aprimoramento provê um armazenamento de tanque ou fluidos para robôs e drones. Sem um destes, ele não será capaz de armazenar fluidos internamente.", + "oc:tooltip.upgradetankcontroller": "Este aprimoramento permite que robôs e drones tenham mais controle de como eles interagem com tanques externos, e permite que ele transfira fluidos para os tanques e dos tanques.", + "oc:tooltip.upgradetractorbeam": "Equipa um dispositivo com uma tecnologia extremamente avançada, codenome \"Imã\". Permite que dispositivos capturem blocos com o raio de 3 blocos de sua localização.", + "oc:tooltip.upgradetrading": "Permite que robôs e drones façam trocas com Aldeões.", + "oc:tooltip.waypoint": "Provê um ponto de referência para os dispositvos com um aprimoramento de navegação.", + "oc:tooltip.wirelessnetworkcard": "Permite enviar mensagens de rede além do meio normal. Você pode ajustar a §fforça do sinal§7 para controlar o quão longe as mensagens vão. Altos níveis de força de sinal resulta em alto consumo de energia.", + "oc:tooltip.worldsensorcard": "Permite ler informações sobre o mundo, como gravidade e/ou se tem uma atmosfera respirável. Use os resultados por sua conta e risco. O fabricando não se responsabiliza por danos corporais ou materias por decisões causadas sobre as saídas dos cartões. Nós temos advogados. E dinheiro. Então nem tente.", + "oc:tooltip.wrench": "Um híbrido entre uma Chave de fenda e uma Chave de boca, esta ferramenta é fácil de usar, mas díficil de dominar.", + "achievement.oc.adapter": "Ai que delicia cara.", + "achievement.oc.adapter.desc": "Interagiu com blocos de outros mods e também do Minecraft vanilla!", + "achievement.oc.assembler": "Explêndido", + "achievement.oc.assembler.desc": "Hora de dominar o mundo!", + "achievement.oc.cable": "Não é um Fio Sujo", + "achievement.oc.cable.desc": "Com a tecnologia patenteada de anti-espaguete.", + "achievement.oc.capacitor": "Baterias inclusas", + "achievement.oc.capacitor.desc": "Você não pode parar isso.", + "achievement.oc.card": "Aceitamos Cartões", + "achievement.oc.card.desc": "Para sua conveniência. Sem segundas intenções, prometo.", + "achievement.oc.case": "Em Caso de Problemas", + "achievement.oc.case.desc": "Porque torres quadradas são as melhores.", + "achievement.oc.charger": "Tá bom, vamo lá", + "achievement.oc.charger.desc": "Carrreeegaaaan- poxa, esqueci do sinal de redstone de novo.", + "achievement.oc.chip": "Todas as Pequenas Coisas", + "achievement.oc.chip.desc": "Porque tubos a vácuo são coisa do passado.", + "achievement.oc.cpu": "Overclocked", + "achievement.oc.cpu.desc": "Hora de fazer uso destes ciclos computacionais.", + "achievement.oc.disassembler": "Vamo quebra tudo!", + "achievement.oc.disassembler.desc": "Caso suas ideias brilhantes não sejam tão brilhantes assim.", + "achievement.oc.diskDrive": "Roda a Roda.", + "achievement.oc.diskDrive.desc": "Capacidade inferior mas um som lindíssimo.", + "achievement.oc.drone": "Voando alto.", + "achievement.oc.drone.desc": "Mantenha a calma e jogue-o para fora do planeta.", + "achievement.oc.eeprom": "Só pode ter um", + "achievement.oc.eeprom.desc": "Por computador, claro. Para manter a ordem da inicialização, entendeu?", + "achievement.oc.floppy": "Um ri- disco", + "achievement.oc.floppy.desc": "Velho, mas ainda funciona.", + "achievement.oc.geolyzer": "Pra dentro da Terra", + "achievement.oc.geolyzer.desc": "Têm qualidades extraordinárias.", + "achievement.oc.graphicsCard": "Ultima Geração", + "achievement.oc.graphicsCard.desc": "Assim pode ser ... ann... rendereziado. Ah sim sim.", + "achievement.oc.hdd": "HDD Melhor que HD", + "achievement.oc.hdd.desc": "Não espere, não é isso que significa. Bom, você entendeu...", + "achievement.oc.hologram": "Próxima Dimensão", + "achievement.oc.hologram.desc": "Porque 2D é chato. Ou não é?", + "achievement.oc.keyboard": "PegadorDeSujeira3000", + "achievement.oc.keyboard.desc": "É altamente recomendável resistir o impulso de girar eles no ar.", + "achievement.oc.microcontroller": "Irmanzinha", + "achievement.oc.microcontroller.desc": "O irmãozinho do computador.", + "achievement.oc.motionSensor": "Mexe ae que quero vê", + "achievement.oc.motionSensor.desc": "Igual a Steve Swagger.", + "achievement.oc.networkCard": "Agora Estamos Falando!", + "achievement.oc.networkCard.desc": "Mantenha contato com esses parentes distantes.", + "achievement.oc.openOS": "Buti", + "achievement.oc.openOS.desc": "Um SO para - espere, já usei essa antes? Droga.", + "achievement.oc.powerDistributor": "Compartilhar é Amar", + "achievement.oc.powerDistributor.desc": "Quando você precisa de ajuda para equilibrar toda essa energia.", + "achievement.oc.rack": "Mas que potência", + "achievement.oc.rack.desc": "Sim, os racks de servidores são potentes.", + "achievement.oc.raid": "LFG", + "achievement.oc.raid.desc": "Heroíco valeuflws.", + "achievement.oc.ram": "Random Access Memories (Memórias de Acesso Aleatório)", + "achievement.oc.ram.desc": "Parabéns, Você está fazendo isso certo.", + "achievement.oc.redstoneCard": "Con... tato", + "achievement.oc.redstoneCard.desc": "Hora de ser análogo.", + "achievement.oc.redstoneIO": "Hello from the outside...", + "achievement.oc.redstoneIO.desc": "Levando os sinais de redstone para onde quiser.", + "achievement.oc.robot": "Bip Bip", + "achievement.oc.robot.desc": "EXTERMINAR!", + "achievement.oc.screen": "Tentou desligar e ligar de novo?", + "achievement.oc.screen.desc": "Não, de verdade. Um pulso de redstone pode alternar o monitor entre ligado e desligado.", + "achievement.oc.server": "Dedicado", + "achievement.oc.server.desc": "Servidores na nuvem, aqui vamos nós.", + "achievement.oc.switch": "Topologia Complexa", + "achievement.oc.switch.desc": "Evite embalagens baratas devido a possibilidade de pacotes perdidos.", + "achievement.oc.tablet": "Não Engula", + "achievement.oc.tablet.desc": "Mantenha longe do alcance das crianças para evitar cobranças exageradas no seu cartão de crédito.", + "achievement.oc.transistor": "Onipresente", + "achievement.oc.transistor.desc": "Crie um Transistor para começar.", + "achievement.oc.wirelessNetworkCard": "Sinais", + "achievement.oc.wirelessNetworkCard.desc": "Hora de ir onde nenhum pacote foi antes.", + "death.attack.oc.nanomachinesOverload.1": "%s foi muito ganancioso.", + "death.attack.oc.nanomachinesOverload.2": "%s teve um ataque de nervos.", + "death.attack.oc.nanomachinesOverload.3": "As nanomáquinas de %s estão fora de controle.", + "death.attack.oc.nanomachinesHungry.1": "%s foi comido por nanomáquinas.", + "death.attack.oc.nanomachinesHungry.2": "%s não alimentou suas nanomáquinas.", + "death.attack.oc.nanomachinesHungry.3": "%s foi digerido.", + "nei.options.inventory.oredict": "Mostre nomes do OreDictionary", + "nei.options.inventory.oredict.true": "Sim", + "nei.options.inventory.oredict.false": "Não", + "nei.usage.oc.Manual": "Open Manual", + "option.oc.address": "Endereço", + "option.oc.componentName": "Nome do Componente", + "option.oc.energy": "Energia" +} diff --git a/src/main/resources/assets/opencomputers/lang/pt_pt.json b/src/main/resources/assets/opencomputers/lang/pt_pt.json new file mode 100644 index 0000000000..d6545483d0 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/pt_pt.json @@ -0,0 +1,118 @@ +{ + "tile.oc.adapter": "Adaptador", + "tile.oc.cable": "Cabo", + "tile.oc.capacitor": "Condensador", + "tile.oc.case1": "Caixa Básica", + "tile.oc.case2": "Caixa Avançada", + "tile.oc.case3": "Caixa Superior", + "tile.oc.charger": "Carregador", + "tile.oc.diskdrive": "Drive de Disquetes", + "tile.oc.keyboard": "Teclado", + "tile.oc.powerconverter": "Conversor de Energia", + "tile.oc.powerdistributor": "Distribuidor de Energia", + "tile.oc.redstone": "E/S de Redstone", + "tile.oc.robot": "Robô", + "tile.oc.robotafterimage": "Robô", + "tile.oc.screen1": "Ecrã Básico", + "tile.oc.screen2": "Ecrã Avançado", + "tile.oc.screen3": "Ecrã Superior", + "tile.oc.switch": "Roteador", + "item.oc.acid": "Grogue", + "item.oc.alu": "Unidade Aritmética e Lógica", + "item.oc.analyzer": "Analizador", + "item.oc.arrowkeys": "Setas", + "item.oc.buttongroup": "Grupo de Botões", + "item.oc.cardbase": "Placa Base", + "item.oc.circuitboard": "Placa de Circuitos", + "item.oc.controlunit": "Unidade de Controlo", + "item.oc.cpu": "Processador", + "item.oc.cuttingwire": "Arame de Corte", + "item.oc.disk": "Disco", + "item.oc.floppydisk": "Disquete", + "item.oc.graphicscard0": "Placa Gráfica Básica", + "item.oc.graphicscard1": "Placa Gráfica Avançada", + "item.oc.graphicscard2": "Placa Gráfica Superior", + "item.oc.harddiskdrive": "Disco Rígido", + "item.oc.ironnugget": "Pepita de Ferro", + "item.oc.memory": "Memória", + "item.oc.microchip0": "Circuito Integrado Simples", + "item.oc.microchip1": "Circuito Integrado Avançado", + "item.oc.microchip2": "Circuito Integrado Superior", + "item.oc.networkcard": "Placa de Rede", + "item.oc.numpad": "Teclado Numérico", + "item.oc.printedcircuitboard": "Placa de Circuitos Impressos", + "item.oc.rawcircuitboard": "Placa de Circuitos Vazia", + "item.oc.redstonecard": "Placa de Redstone", + "item.oc.transistor": "Transístor", + "item.oc.upgradecrafting": "Melhoramento: Fabrico", + "item.oc.upgradegenerator": "Melhoramento: Gerador", + "item.oc.upgradenavigation": "Melhoramento: Navegação", + "item.oc.upgradesign": "Melhoramento: Escrita e Leitura de Placas", + "item.oc.upgradesolargenerator": "Melhoramento: Gerador Solar", + "item.oc.wirelessnetworkcard0": "Placa de Rede sem Fios", + "item.oc.WirelessNetworkCard1": "Placa de Rede sem Fios", + "itemGroup.OpenComputers": "OpenComputers", + "oc:gui.Analyzer.Address": "§6Endereço§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Nome do Componente§f: %s", + "oc:gui.Analyzer.LastError": "§6Último erro§f: %s", + "oc:gui.Analyzer.RobotName": "§6Nome§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Proprietário§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Experiência§f: %s", + "oc:gui.Analyzer.StoredEnergy": "§6Energia Armazenada§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Total de Energia Armazenada§f: %s", + "oc:gui.Analyzer.Users": "§6Utilizadores§f: %s", + "oc:gui.Robot.Power": "Energia", + "oc:gui.Robot.TurnOff": "Desligar", + "oc:gui.Robot.TurnOn": "Ligar", + "oc:container.case": "Computador", + "oc:container.charger": "Carregador", + "oc:container.diskdrive": "Drive de Disquetes", + "oc:container.switch": "Roteador", + "oc:tooltip.acid": "Um líquido muito tóxico, geralmente apenas consumido por alguns piratas. Graças à sua natureza corrosiva é perfeito para gravar placas de circuitos.", + "oc:tooltip.adapter": "Usado para controlar blocos que não sejam componentes, tais como blocos do Minecraft Vanilla ou de outros mods.", + "oc:tooltip.alu": "Faz cálculos por ti. Talvez seja melhor assim.", + "oc:tooltip.analyzer": "Usado para mostrar informação acerca de blocos, tais como o seu §fendereço§7 e §fnome de componente§7.\ntambém mostra o erro que fez o computador crashar caso este não se tenha desligado normalmente.", + "oc:tooltip.cable": "Uma forma barata de conectar blocos.", + "oc:tooltip.capacitor": "Armazena energia para ser usada mais tarde. Pode encher e esvaziar-se muito rapidamente.", + "oc:tooltip.cardbase": "Como o nome indica, é o componente básico para construir placas de expansão.", + "oc:tooltip.case": "A Caixa é o bloco básico para a construção de computadores e contém as §fplacas de expansão§7, §fRAM§7 e §fdiscos rígidos§7.\nSlots: §f%s§7", + "oc:tooltip.charger": "Transfere energia dos condensadores para robôs adjacentes. A taxa de transferência depende do §fsinal de redstone§7 aplicado, onde nenhum sinal significa não carregar, e o sinal máximo significa carregar à velocidade máxima.", + "oc:tooltip.circuitboard": "Agora estamos a chegar a algum lado. Pode ser gravada para obter uma placa de circuitos impressos.", + "oc:tooltip.controlunit": "Esta é a unidade que... controla... coisas. Precisas dela para montar um Processador. Portanto, sim, pode-se dizer que é importante.", + "oc:tooltip.cpu": "Um componente essencial de qualquer computador. A frequencia é pouco fiável, mas o que é que esperas quando corre com um relógio de sol?", + "oc:tooltip.cuttingwire": "Usado para cortar blocos de barro na forma de uma placa. Parte-se ao fim de um uso, o que faz dela a ferramenta menos eficiente de sempre.", + "oc:tooltip.disk": "Um meio primitivo que pode ser usado para construir dispositivos de armazenamento persistente.", + "oc:tooltip.diskdrive.CC": "Disquetes do ComputerCraft são §asuportadas§7.", + "oc:tooltip.diskdrive": "Permite ler e escrever dados em Disquetes.", + "oc:tooltip.graphicscard": "Usado para alterar o que é mostrado nos ecrãs.\nResolução máxima: §f%sx%s§7\nProfundidade de cor máxima: §f%s§7\nOperações/ciclo: §f%s§7", + "oc:tooltip.ironnugget": "Uma pepita feita de ferro, por isso é que se chama Pepita de Ferro, duh...", + "oc:tooltip.keyboard": "Pode ligar-se a um ecrã para permitir escrever através dele.", + "oc:tooltip.memory": "Necessária para poder usar um computador. Quanta mais RAM tiveres, mais complexos são os programas que podes correr.", + "oc:tooltip.microchip": "Um chip antes conhecido por Circuito Integrado. Não faço ideia como é que isto funciona com redstone, mas funciona.", + "oc:tooltip.networkcard": "Permite a computadores distantes ligados por blocos (tais como Cabos) comunicar enviando mensagens entre eles.", + "oc:tooltip.powerconverter.BuildCraft": "§fMJ de Buildcraft§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fEU de IndustrialCraft²§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fRF de Thermal Expansion§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fCoulombs de Resonant Engine§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Converte energia de outros mods para o tipo de energia usado internamente. Taxas de conversão:", + "oc:tooltip.powerdistributor": "Distribui energia entre diferentes redes. É util para alimentar várias redes separadas através de uma fonte de energia partilhada.", + "oc:tooltip.printedcircuitboard": "O componente básico de placas de expansão, memórias e afins.", + "oc:tooltip.rawcircuitboard": "Pode ser endurecida em qualquer fornalha.", + "oc:tooltip.redstone": "Permite receber e emitir sinais de redstone. Pode ser controlado por qualquer computador ao qual o bloco esteja conectado. Basicamente isto é uma placa de controlo de redstone.", + "oc:tooltip.redstonecard.RedLogic": "§fRedLogic§7 é §asuportado§7.", + "oc:tooltip.redstonecard.RedNet": "§fRedNet§7 é §asuportado§7.", + "oc:tooltip.redstonecard": "Permite ao computador ou robô receber e emitir sinais de redstone.", + "oc:tooltip.robot": "Ao contrário dos computadores, os robôs podem mover-se e interagir com o mundo como um jogado. No entanto, eles §onão§r§7 podem interagir com componentes externos!", + "oc:tooltip.robot_level": "§fNível§7: §a%s§7.", + "oc:tooltip.robot_storedenergy": "§fEnergia Armazenada§7: §a%s§7.", + "oc:tooltip.screen": "Mostra texto, controlado por uma placa gráfica numa Caixa.\nResolução máxima: §f%sx%s§7\nProfundidade de cor máxima: §f%s§7", + "oc:tooltip.switch": "Permite interligar redes diferentes. Apenas pacotes de rede serão passados, componentes não serão visiveis em redes vizinhas. Usa isto para separar várias redes e ao mesmo tempo permitir comunicação através de placas de rede, por exemplo.", + "oc:tooltip.toolong": "Prime [§f%s§7] para uma descrição detalhada.", + "oc:tooltip.transistor": "Um componente básico do hardware do computador. É um pouco retorcido, mas faz o seu trabalho.", + "oc:tooltip.upgradecrafting": "Permite aos robôs usar a parte superior esquerda do seu inventório para fabricar objectos. Os itens têm de estar alinhados como numa mesa de fabrico.", + "oc:tooltip.upgradegenerator": "Pode ser usado para gerar energia a partir de combustível. Queima itens para gerar energia ao longo do tempo, dependendo da energia que pode ser extraída de cada componente.\n§fEficiência§7: §a%s%%§7", + "oc:tooltip.upgradenavigation": "Pode ser usado para determinar a posição e orientação do robô. A posição é relativa ao centro do mapa usado para fabricar este melhoramento.", + "oc:tooltip.upgradesign": "Permiter ler e escrever texto em Placas.", + "oc:tooltip.upgradesolargenerator": "Pode ser usado para gerar energia a partir da luz solar. Requer exposição directa à luz solar. Gera energia a %s%% da velocidade de um motor a carvão.", + "oc:tooltip.wirelessnetworkcard": "Permite trocar mensagens em redes com e sem fios. Certifica-te que defines a §fforça do sinal§7 ou nenhum pacote será enviado via redes sem fios!" +} diff --git a/src/main/resources/assets/opencomputers/lang/ru_RU.lang b/src/main/resources/assets/opencomputers/lang/ru_RU.lang deleted file mode 100644 index d85e8a8782..0000000000 --- a/src/main/resources/assets/opencomputers/lang/ru_RU.lang +++ /dev/null @@ -1,482 +0,0 @@ -# This is the Russian localization file. -# Authors: YuRaNnNzZZ, Sodiet, Adaptivity, cyber01, makkarpov, dangranos -# Use [nl] to for a line break. - -# Blocks -tile.oc.accesspoint.name=§cТочка доступа§7 -tile.oc.adapter.name=Адаптер -tile.oc.assembler.name=Сборщик -tile.oc.cable.name=Кабель -tile.oc.capacitor.name=Конденсатор энергии -tile.oc.case1.name=Системный блок (1-ый уровень) -tile.oc.case2.name=Системный блок (2-ой уровень) -tile.oc.case3.name=Системный блок (3-ий уровень) -tile.oc.casecreative.name=Системный блок (Творческий) -tile.oc.chameliumblock.name=Блок хамелиума -tile.oc.charger.name=Зарядное устройство -tile.oc.disassembler.name=Разборщик -tile.oc.diskdrive.name=Дисковод -tile.oc.endstone.name=Камень края -tile.oc.geolyzer.name=Геоанализатор -tile.oc.hologram1.name=Голографический проектор (1-ый уровень) -tile.oc.hologram2.name=Голографический проектор (2-ой уровень) -tile.oc.keyboard.name=Клавиатура -tile.oc.microcontroller.name=Микроконтроллер -tile.oc.motionsensor.name=Датчик движения -tile.oc.netsplitter.name=Сетевой переключатель -tile.oc.powerconverter.name=Преобразователь энергии -tile.oc.powerdistributor.name=Распределитель энергии -tile.oc.print.name=3D модель -tile.oc.printer.name=3D принтер -tile.oc.raid.name=RAID -tile.oc.redstone.name=Красный контроллер -tile.oc.relay.name=Ретранслятор -tile.oc.robot.name=Робот -tile.oc.robotafterimage.name=Робот -tile.oc.screen1.name=Монитор (1-ый уровень) -tile.oc.screen2.name=Монитор (2-ой уровень) -tile.oc.screen3.name=Монитор (3-ий уровень) -tile.oc.rack.name=Серверная стойка -tile.oc.switch.name=§cКоммутатор§7 -tile.oc.transposer.name=Транспозер -tile.oc.waypoint.name=Путевая точка - -# Items -item.oc.abstractbuscard.name=Карта абстрактной шины -item.oc.acid.name=Кислота -item.oc.alu.name=Арифметико-логическое устройство (АЛУ) -item.oc.analyzer.name=Анализатор -item.oc.apu0.name=Процессор с видеокартой (APU) (1-ый уровень) -item.oc.apu1.name=Процессор с видеокартой (APU) (2-ой уровень) -item.oc.apu2.name=Процессор с видеокартой (APU) (Творческий) -item.oc.arrowkeys.name=Клавиши со стрелками -item.oc.buttongroup.name=Группа кнопок -item.oc.cardbase.name=Основа для карт -item.oc.chamelium.name=Хамелиум -item.oc.circuitboard.name=Нетравленая печатная плата -item.oc.componentbus0.name=Компонентная шина (1-ый уровень) -item.oc.componentbus1.name=Компонентная шина (2-ой уровень) -item.oc.componentbus2.name=Компонентная шина (3-ий уровень) -item.oc.controlunit.name=Устройство управления (УУ) -item.oc.cpu0.name=Центральный процессор (ЦП) (1-ый уровень) -item.oc.cpu1.name=Центральный процессор (ЦП) (2-ой уровень) -item.oc.cpu2.name=Центральный процессор (ЦП) (3-ий уровень) -item.oc.cuttingwire.name=Проволока -item.oc.datacard0.name=Карта данных (1-ый уровень) -item.oc.datacard1.name=Карта данных (2-ой уровень) -item.oc.datacard2.name=Карта данных (3-ий уровень) -item.oc.debugcard.name=Отладочная карта -item.oc.debugger.name=Сетевой отладчик -item.oc.diamondchip.name=Алмазный обломок -item.oc.disk.name=Металлический диск -item.oc.diskdrivemountable.name=Дисковод (для серверной стойки) -item.oc.drone.name=Дрон -item.oc.dronecase0.name=Корпус дрона (1-ый уровень) -item.oc.dronecase1.name=Корпус дрона (2-ой уровень) -item.oc.dronecase3.name=Корпус дрона (Креатив) -item.oc.eeprom.name=EEPROM -item.oc.floppydisk.name=Дискета -item.oc.graphicscard0.name=Видеокарта (1-ый уровень) -item.oc.graphicscard1.name=Видеокарта (2-ой уровень) -item.oc.graphicscard2.name=Видеокарта (3-ий уровень) -item.oc.harddiskdrive0.name=Жёсткий диск (1-ый уровень) -item.oc.harddiskdrive1.name=Жёсткий диск (2-ой уровень) -item.oc.harddiskdrive2.name=Жёсткий диск (3-ий уровень) -item.oc.hoverboots.name=Парящие ботинки -item.oc.inkcartridge.name=Картридж с чернилами -item.oc.inkcartridgeempty.name=Картридж с чернилами (Пустой) -item.oc.internetcard.name=Интернет карта -item.oc.interweb.name=Интерпаутина -item.oc.ironnugget.name=Железный самородок -item.oc.linkedcard.name=Соединённая карта -item.oc.manual.name=Руководство OpenComputers -item.oc.memory0.name=Память (1-ый уровень) -item.oc.memory1.name=Память (Уровень 1.5) -item.oc.memory2.name=Память (2-ой уровень) -item.oc.memory3.name=Память (Уровень 2.5) -item.oc.memory4.name=Память (3-ий уровень) -item.oc.memory5.name=Память (Уровень 3.5) -item.oc.microchip0.name=Микрочип (1-ый уровень) -item.oc.microchip1.name=Микрочип (2-ой уровень) -item.oc.microchip2.name=Микрочип (3-ий уровень) -item.oc.microcontrollercase0.name=Корпус микроконтроллера (1-ый уровень) -item.oc.microcontrollercase1.name=Корпус микроконтроллера (2-ой уровень) -item.oc.microcontrollercase3.name=Корпус микроконтроллера (Креатив) -item.oc.nanomachines.name=Нанороботы -item.oc.networkcard.name=Сетевая карта -item.oc.numpad.name=Цифровой блок клавиш -item.oc.present.name=Маленькое что-то... -item.oc.printedcircuitboard.name=Печатная плата -item.oc.rawcircuitboard.name=Основа для печатной платы -item.oc.redstonecard0.name=Плата на красном камне (1-ый уровень) -item.oc.redstonecard1.name=Плата на красном камне (2-ой уровень) -item.oc.server0.name=Сервер (1-ый уровень) -item.oc.server1.name=Сервер (2-ой уровень) -item.oc.server2.name=Сервер (3-ий уровень) -item.oc.server3.name=Сервер (Творческий) -item.oc.tablet.name=Планшет -item.oc.tabletcase0.name=Корпус планшета (1-ый уровень) -item.oc.tabletcase1.name=Корпус планшета (2-ой уровень) -item.oc.tabletcase3.name=Корпус планшета (Креатив) -item.oc.terminal.name=Беспроводной терминал -item.oc.terminalserver.name=Терминальный сервер -item.oc.texturepicker.name=Определитель текстур -item.oc.transistor.name=Транзистор -item.oc.upgradeangel.name="Ангельское" улучшение -item.oc.upgradebattery0.name=Улучшение "Ёмкость" (1-ый уровень) -item.oc.upgradebattery1.name=Улучшение "Ёмкость" (2-ой уровень) -item.oc.upgradebattery2.name=Улучшение "Ёмкость" (3-ий уровень) -item.oc.upgradechunkloader.name=Улучшение "Загрузчик чанков" -item.oc.upgradecontainercard0.name=Контейнер для карты (1-ый уровень) -item.oc.upgradecontainercard1.name=Контейнер для карты (2-ой уровень) -item.oc.upgradecontainercard2.name=Контейнер для карты (3-ий уровень) -item.oc.upgradecontainerupgrade0.name=Контейнер для улучшения (1-ый уровень) -item.oc.upgradecontainerupgrade1.name=Контейнер для улучшения (2-ой уровень) -item.oc.upgradecontainerupgrade2.name=Контейнер для улучшения (3-ий уровень) -item.oc.upgradecrafting.name=Улучшение "Верстак" -item.oc.upgradedatabase0.name=Улучшение "База данных" (1-ый уровень) -item.oc.upgradedatabase1.name=Улучшение "База данных" (2-ой уровень) -item.oc.upgradedatabase2.name=Улучшение "База данных" (3-ий уровень) -item.oc.upgradeexperience.name=Улучшение "Опыт" -item.oc.upgradegenerator.name=Улучшение "Генератор" -item.oc.upgradehover0.name=Улучшение "Парение" (1-ый уровень) -item.oc.upgradehover1.name=Улучшение "Парение" (2-ый уровень) -item.oc.upgradeinventory.name=Улучшение "Инвентарь" -item.oc.upgradeinventorycontroller.name=Улучшение "Контроллер инвентаря" -item.oc.upgradeleash.name=Улучшение "Поводок" -item.oc.upgrademf.name=МФУ -item.oc.upgradenavigation.name=Улучшение "Навигация" -item.oc.upgradepiston.name=Улучшение "Поршень" -item.oc.upgradesign.name=Улучшение "Контроллер табличек" -item.oc.upgradesolargenerator.name=Улучшение "Солнечный генератор" -item.oc.upgradetank.name=Улучшение "Бак для жидкостей" -item.oc.upgradetankcontroller.name=Улучшение "Контроллер бака" -item.oc.upgradetractorbeam.name=Улучшение "Притягивающий луч" -item.oc.upgradetrading.name=Улучшение "Торговля" -item.oc.wirelessnetworkcard0.name=Плата беспроводной сети (1-ый уровень) -item.oc.wirelessnetworkcard1.name=Плата беспроводной сети (2-ой уровень) -item.oc.worldsensorcard.name=Карта-мировой сенсор -item.oc.wrench.name=Ключ - -# Entities -entity.oc.Drone.name=Дрон - -# GUI -oc:gui.Analyzer.Address=§6Адрес§f: %s -oc:gui.Analyzer.AddressCopied=Адрес скопирован в буфер обмена. -oc:gui.Analyzer.ChargerSpeed=§6Скорость зарядки§f: %s -oc:gui.Analyzer.ComponentName=§6Имя компонента§f: %s -oc:gui.Analyzer.Components=§6Количество подключенных компонентов§f: %s -oc:gui.Analyzer.CopyToClipboard=Кликните для копирования в буфер обмена. -oc:gui.Analyzer.LastError=§6Последняя ошибка§f: %s -oc:gui.Analyzer.RobotName=§6Имя§f: %s -oc:gui.Analyzer.RobotOwner=§6Владелец§f: %s -oc:gui.Analyzer.RobotXp=§6Опыт§f: %s (Уровень: %s) -oc:gui.Analyzer.StoredEnergy=§6Накоплено энергии§f: %s -oc:gui.Analyzer.TotalEnergy=§6Всего накоплено энергии§f: %s -oc:gui.Analyzer.Users=§6Пользователи§f: %s -oc:gui.Analyzer.WirelessStrength=§6Уровень сигнала§f: %s -oc:gui.Assembler.Collect=Заберите результат сборки -oc:gui.Assembler.Complexity=Сложность: %s/%s -oc:gui.Assembler.InsertCase=Вставьте системный блок -oc:gui.Assembler.InsertCPU=Вставьте процессор -oc:gui.Assembler.InsertRAM=Вставьте память -oc:gui.Assembler.Progress=Прогресс: %s%% (%s) -oc:gui.Assembler.Run=Собрать -oc:gui.Assembler.Warning.BIOS=BIOS -oc:gui.Assembler.Warning.GraphicsCard=Видеокарта -oc:gui.Assembler.Warning.Inventory=Улучшение "Инвентарь" -oc:gui.Assembler.Warning.Keyboard=Клавиатура -oc:gui.Assembler.Warning.OS=Загрузочный диск -oc:gui.Assembler.Warning.Screen=Монитор -oc:gui.Assembler.Warnings=§eВнимание§7: Отсутствуют рекомендуемые компоненты. -oc:gui.Chat.NewVersion=Доступна новая версия: %s -oc:gui.Chat.TextureName=§7Имя текстуры: §a%s§f. -oc:gui.Chat.WarningClassTransformer=Возникли §cошибки§f при преобразовании классов. Пожалуйста, сообщите об этом, а также приложите файл FML §alatest.log§f/§afml-server-latest.log§f! -oc:gui.Chat.WarningFingerprint=§cВНИМАНИЕ§f - несовпадение отпечатка файла! Ожидаемый: '§a%s§f', полученный: '§e%s§f'. Если Вы не разработчик, использующий деобфусцированную версию мода, то §lкрайне§f желательно заново скачать OpenComputers, поскольку JAR-файл, возможно, был изменён. -oc:gui.Chat.WarningLink=Невозможно открыть ссылку: %s -oc:gui.Chat.WarningLuaFallback=Исходные библиотеки Lua не доступны, компьютеры не смогут сохранять своё состояние. Они перезагрузятся после выгрузки чанка. -oc:gui.Chat.WarningProjectRed=Вы используете версию Project: Red, несовместимую с OpenComputers. Попробуйте обновить Project: Red. -oc:gui.Chat.WarningRecipes=Произошла ошибка при загрузке одного или нескольких рецептов. Некоторые предметы могут не крафтиться. Проверьте логи, чобы узнать подробнее. -oc:gui.Chat.WarningSimpleComponent=Некоторый мод §eневерно§f использует интрефейс §aSimpleComponent§f. Логика компонента не смогла быть внедрена. Проверьте логи, чобы узнать подробнее. -oc:gui.Drive.Managed=Файловый режим -oc:gui.Drive.Unmanaged=Блочный режим -oc:gui.Drive.Warning=§lВнимание§r: переключение режимов очищает диск! -oc:gui.Error.ComponentOverflow=Слишком много компонентов подключено к компьютеру. -oc:gui.Error.InternalError=Возникла внутренняя ошибка, пожалуйста, посмотрите лог-файл. Возможно, это баг. -oc:gui.Error.NoCPU=Не установлен процессор. -oc:gui.Error.NoEnergy=Недостаточно энергии. -oc:gui.Error.NoRAM=Не установлена память. -oc:gui.Error.OutOfMemory=Недостаточно памяти. -oc:gui.Manual.Blocks=Блоки OpenComputers -oc:gui.Manual.Home=Главная страница -oc:gui.Manual.Items=Предметы OpenComputers -oc:gui.Manual.Warning.BlockMissing=Блок недоступен. -oc:gui.Manual.Warning.ImageMissing=Изображение не найдено. -oc:gui.Manual.Warning.ItemMissing=Предмет недоступен. -oc:gui.Manual.Warning.OreDictMissing=Запись Ore Dictionary недоступна. -oc:gui.Raid.Warning=§4Добавление диска очистит его.[nl] Удаление диска очистит RAID. -oc:gui.Robot.Power=Энергия -oc:gui.Robot.TurnOff=Выключить -oc:gui.Robot.TurnOn=Включить -oc:gui.Rack.Back=Сзади -oc:gui.Rack.Bottom=Снизу -oc:gui.Rack.Left=Слева -oc:gui.Rack.None=Нет -oc:gui.Rack.Right=Справа -oc:gui.Rack.Enabled=Включено -oc:gui.Rack.Disabled=Выключено -oc:gui.Rack.Top=Сверху -oc:gui.Switch.TransferRate=Цикличность -oc:gui.Switch.PacketsPerCycle=Пакеты / цикл -oc:gui.Switch.QueueSize=Размер очереди -oc:gui.Terminal.InvalidKey=Неверный ключ, скорее всего, к серверу уже подключен другой терминал. -oc:gui.Terminal.OutOfRange=Нет сигнала. - -# Containers -oc:container.accesspoint=Точка доступа -oc:container.adapter=Адаптер -oc:container.case=Компьютер -oc:container.charger=Зарядное устройство -oc:container.disassembler=Разборщик -oc:container.diskdrive=Дисковод -oc:container.printer=Принтер -oc:container.raid=RAID -oc:container.relay=Ретранслятор -oc:container.server=Сервер -oc:container.rack=Серверная стойка -oc:container.switch=Коммутатор -oc:container.tabletwrapper=Планшет - -# Keybinds -key.clipboardPaste=Вставить из буфера обмена -key.materialCosts=Показать стоимость в материалах - -# Item / Block Tooltips -oc:tooltip.accesspoint=Работает как коммутатор, но и с беспроводными сетями. -oc:tooltip.abstractbuscard=Обеспечивает взаимодействие с абстрактной шиной из §fStargateTech 2§7 (отправка и приём LIP-пакетов). -oc:tooltip.acid=Высокотоксичная псевдо-жидкость, которую обычно пьют только определённые пираты. Однако может быть полезна и при других применениях. -oc:tooltip.adapter=Используется для контроля некомпонентных блоков, таких как обычные блоки или блоки из других модов. -oc:tooltip.alu=Выполняет арифметические вычисления, так что вам не придётся возиться с ними. -oc:tooltip.analyzer=Используется для отображения информации о блоках, такой как §fадрес§7 или §fимя компонента§7.[nl] Также отображает ошибку, вызвавшую сбой компьютера. -oc:tooltip.apu=Это процессор со встроенной видеокартой, полезный, когда вам требуется освободить ещё один слот для карт.[nl] Поддерживается компонентов: §f%s§7[nl] Максимальное разрешение: §f%sx%s§7[nl] Максимальная глубина цвета: §f%s§7[nl] Операций в тик: §f%s§7 -oc:tooltip.assembler=Позволяет собирать роботов и другие устройства из ряда различных частей компьютера. -oc:tooltip.cable=Простой и дешёвый способ соединить компоненты между собой. -oc:tooltip.capacitor=Накапливает энергию для дальнейшего использования. Может быть очень быстро заполнен и опустошён. -oc:tooltip.cardbase=Как видно из названия, это основа для всех карт расширения. -oc:tooltip.case=Системный блок - основа компьютера, содержащий §fкарты расширения§7, §fОЗУ§7 и §fжёсткие диски§7.[nl] Слотов: §f%s§7 -oc:tooltip.chamelium=Базовый материал для 3D печати. Не глотать: может привести к слепоте и временным отсутствием присутствия. -oc:tooltip.chameliumblock=Удобен для окрашенных 3D моделей или просто как цветной блок для вашей базы. -oc:tooltip.charger=Передаёт энергию из аккумуляторов вплотную находящимся роботам и дронам. Скорость передачи зависит от §fсилы сигнала красного камня§7: отсутствие сигнала означает "не заряжать", а полный сигнал - "заряжать на полной скорости". -oc:tooltip.circuitboard=Мы уже очень близки. Может быть вытравлена, чтобы получить печатную плату. -oc:tooltip.controlunit=Это штука, которая... контролирует... что-то. Она необходима, чтобы создать центральный процессор. Так что, да, она очень важна. -oc:tooltip.componentbus=Позволяет серверам взаимодействовать с большим количеством компонентов.[nl] Поддерживается компонентов: §f%s§7 -oc:tooltip.cpu=Является важным компонентом в компьютере. Тактовая частота немного нестабильна, но что вы ожидали, если он работает на карманных солнечных часах. Количество поддерживаемых компонентов: §f%s§7 -oc:tooltip.cpu.architecture=Архитектура: §f%s§7 -oc:tooltip.cuttingwire=Используется для нарезки глиняных блоков в пластины. Рвётся после использования, что делает её, пожалуй, самым неэффективным инструментом. -oc:tooltip.datacard0=Обеспечивает поддержку нескольких продвинутых алгоритмов, таких как хеширование и сжатие. -oc:tooltip.datacard1=Обеспечивает поддержку нескольких продвинутых алгоритмов, таких как AES-шифрование, хеширование и сжатие. -oc:tooltip.datacard2=Обеспечивает поддержку нескольких продвинутых алгоритмов, таких как AES-шифрование, эллиптическая криптография, хеширование и сжатие. -oc:tooltip.debugcard=Креативный предмет, позволяет манипулировать игровым миром. Используйте на свой страх и риск. -oc:tooltip.debugger=Может быть использован для вывода отладочной информации о внутренней сети. Используйте только тогда, когда попросил разработчик. -oc:tooltip.diamondchip=Небольшой кусочек некогда сияющего алмаза. Он больше никогда не будет таким, как прежде. -oc:tooltip.disassembler=Разделяет предметы на исходные компоненты. §lВнимание§7: возвращённые предметы имеют шанс %s%% сломаться! -oc:tooltip.disk=Примитивный носитель, который может быть использован для создания постоянных запоминающих устройств. -oc:tooltip.diskdrive.cc=§aПоддерживаются§7 дискеты из ComputerCraft. -oc:tooltip.diskdrive=Позволяет читать и записывать дискеты. Может быть установлен в роботов, что позволит затем вставлять дискеты. -oc:tooltip.diskdrivemountable=Работает так же, как и обычный дисковод, но может быть вставлен только в серверную стойку. -oc:tooltip.diskusage=Занято %s/%s байт -oc:tooltip.diskmodemanaged=Режим: файловый -oc:tooltip.diskmodeunmanaged=Режим: блочный -oc:tooltip.drone=Дроны это легкие и быстрые устройства, но с ограниченным инвентарем. -oc:tooltip.dronecase=Корпус, предназначенный для создания дрона в сборщике. Вмещает малое количество компонентов и предоставляет левитацию с помощью силы камня края. -oc:tooltip.eeprom=Маленькое программируемое хранилище, которое содержит BIOS для запуска компьютеров. -oc:tooltip.fakeendstone=Почти такой же, как и настоящий камень края, даже эмулирует его легкость! -oc:tooltip.geolyzer=Позволяет сканировать твёрдость блоков в окрестности. Эта информация может быть полезна для создания голограммы области или для обнаружения руд. -oc:tooltip.graphicscard=Используется для изменения того, что отображается на мониторах.[nl] Максимальное разрешение: §f%sx%s§7[nl] Максимальная глубина цвета:§f%s§7[nl] Операций/такт: §f%s§7 -oc:tooltip.hoverboots=Прыгайте выше, падайте глубже, бегайте быстрее. Это и многое другое с нашими новыми Парящими ботинками (TM). -oc:tooltip.inkcartridge=Используется в 3D печати. По таинственным причинам ему не нужно оставаться в принтере. -oc:tooltip.inkcartridgeempty=Этот картридж выглядит пустым. Заправьте его с помощью красителей. Или выбросьте. -oc:tooltip.internetcard=Эта карта позволяет делать HTTP-запросы и использовать реальные TCP сокеты. -oc:tooltip.interweb=Поздравляем, вы выиграли одну (1) интерсеть. Подключиться к ней можно с помощью Интернет-платы. Осторожно: не кормите троллей. -oc:tooltip.ironnugget=Самородок, созданный из железа. Может, именно поэтому он и назван железным самородком? Хм... -oc:tooltip.keyboard=Присоединяется к монитору, позволяя вводить информацию. -oc:tooltip.hologram0=Объёмный дисплей, управляемый компьютером и использующийся для отображения произвольных воксельных структур.[nl] Разрешение: §f48x32x48§7 [nl] Максимальный масштаб: §f3x§7 [nl] Глубина цвета: §fМонохромный§7 -oc:tooltip.hologram1=Объёмный дисплей, управляемый компьютером и использующийся для отображения произвольных воксельных структур.[nl] Разрешение: §f48x32x48§7 [nl] Максимальный масштаб: §f4x§7 [nl] Глубина цвета: §fТрёхцветный§7 -oc:tooltip.linkedcard=Они изготавливаются в парах и могут общаться только с партнёром. Тем не менее, общаться они могут на любом расстоянии - даже между измерениями. Однако для отправки сообщения нужно довольно много энергии. -oc:tooltip.linkedcard_channel=§8Канал: %s§7 -oc:tooltip.manual=Содержит всю информацию о моде OpenComputers, которая вам может когда-либо понадобиться. И даже больше. По невероятно низкой цене... §oнажмите R для продолжения§7. -oc:tooltip.materialcosts=Удерживайте [§f%s§7] для показа материалов. -oc:tooltip.materials=Материалы: -oc:tooltip.memory=Необходима для запуска компьютера. Чем больше ОЗУ, тем более требовательные программы Вы можете запустить. -oc:tooltip.microchip=Чип, ранее известный как интегральная схема. Понятия не имею почему, но он работает с красным камнем. -oc:tooltip.microcontroller=Микроконтроллеры - это компьютеры, сведённые к самым базовым вещам. Они используются для выполнения специфических задач и выполняют программу, записанную на EEPROM.[nl] §cНе могут взаимодействовать с внешними компонентами.§7 -oc:tooltip.microcontrollercase=Базовый компонент для создания микроконтроллеров. Положите в сборщик, чтобы установить компоненты, и соберите микроконтроллер. -oc:tooltip.motionsensor=Может обнаружить движение ближайших живых существ. Требуется прямая линия видимости. -oc:tooltip.nanomachines=Блок управления и кучка нанороботов для приема внутрь, если вы решились. -oc:tooltip.networkcard=Позволяет обмениваться сообщениями между соединённым друг с другом - с помощью кабеля или других блоков - компьютерами. -oc:tooltip.poweracceptor=Скорость преобразования энергии: §f%s/t§7 -oc:tooltip.powerconverter.buildcraft=§fBuildCraft MJ§7: §a%s:%s§7 -oc:tooltip.powerconverter.factorization=§fFactorization Charge§7: §a%s:%s§7 -oc:tooltip.powerconverter.industrialcraft2=§fIndustrialCraft² EU§7: §a%s:%s§7 -oc:tooltip.powerconverter.mekanism=§fMekanism Joules§7: §a%s:%s§7 -oc:tooltip.powerconverter.thermalexpansion=§fThermal Expansion RF§7: §a%s:%s§7 -oc:tooltip.powerconverter.resonantengine=§fResonant Engine Coulombs§7: §a%s:%s§7 -oc:tooltip.powerconverter=Преобразует энергию из других модов во внутренний тип энергии. Соотношение энергии: -oc:tooltip.powerdistributor=Передаёт энергию между различными сетями. Полезно, если требуется запитать от одного преобразователя несколько сетей, которые должны оставаться разделёнными. -oc:tooltip.present=Откройте этот подарок, чтобы получить немного §kчего-то§7![nl]§8Крафтите предметы OpenComputers в нужное время, чтобы получить шанс получить подарок.§7 -oc:tooltip.print.beaconbase=§8Используется в качестве основы для маяка. -oc:tooltip.print.lightvalue=§8Сила излучаемого света: %s. -oc:tooltip.print.redstonelevel=§8Сила выдаваемого красного сигнала: %s. -oc:tooltip.printedcircuitboard=Основа плат, памяти и прочего. -oc:tooltip.printer=Позволяет печатать пользовательские 3D-модели, используя хамелиум и картриджи с чернилами. Должен быть настроен с помощью компьютера. Держите подальше от детей. -oc:tooltip.raid=Позволяет соединять три жестких диска в единую файловую систему, которую могут использовать все подключенные компьютеры. -oc:tooltip.rawcircuitboard=Может быть закалена в печи для получения печатной платы. -oc:tooltip.redstone=Позволяет считывать и подавать сигналы красного камня вокруг блока. Контролируется любым подключенным компьютером. Иными словами, это что-то вроде внешней платы на красном камне. -oc:tooltip.redstonecard.projectred=Мод §fProjectRed§7 §aподдерживается§7. -oc:tooltip.redstonecard.redlogic=Мод §fRedLogic§7 §aподдерживается§7. -oc:tooltip.redstonecard.rednet=Мод §fRedNet§7 §aподдерживается§7. -oc:tooltip.redstonecard.wirelesscbe=Мод §fWireless Redstone (ChickenBones)§7 §aподдерживается§7. -oc:tooltip.redstonecard.wirelesssv=Мод §fWireless Redstone (SlimeVoid)§7 §aподдерживается§7. -oc:tooltip.redstonecard=Позволяет считывать и подавать сигналы красного камня вокруг компьютера или робота. -oc:tooltip.relay=Позволяет соединять различные сети между собой. Передаются только сообщения, компоненты между сетями не будут доступны. Используйте его для разделения сетей с возможностью пересылать сообщения между ними. -oc:tooltip.robot=В отличие от компьютеров, роботы могут передвигаться и взаимодействовать с миром, как игрок.[nl] §cНе могут подключаться к внешним компонентам.§7 -# The underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fУровень§7: §a%s§7. -oc:tooltip.robot_storedenergy=§fНакопленная энергия§7: §a%s§7. -oc:tooltip.screen=Отображает текст, передаваемый видеокартой.[nl] Максимальное разрешение: §f%sx%s§7[nl] Максимальная глубина цвета: §f%s§7 -oc:tooltip.server=Это сервер. Есть много других, похожих на него, но только этот может быть улучшен компонентами, как системный блок. Можно включить после размещения в серверную стойку. -oc:tooltip.server.components=Установленные компоненты: -oc:tooltip.rack=Обеспечивает работу до четырёх серверов или других монтируемых компонентов. -oc:tooltip.switch=Позволяет соединять различные сети между собой. Передаются только сообщения, компоненты между сетями не будут доступны. Используйте его для разделения сетей с возможностью пересылать сообщения между ними. -oc:tooltip.tablet=Планшет, полностью готовый к работе с Lua. Может быть отключен нажатием правой кнопки мыши + Shift. -oc:tooltip.tabletcase=Простой корпус для планшета. Поместите в сборщик, чтобы вставить компоненты, и соберите себе планшетный компьютер. -oc:tooltip.terminal=Позволяет дистанционно управлять сервером, пока вы находитесь в радиусе его действия. Действует как портативный дисплей с клавиатурой.[nl] Shift+ПКМ по серверу терминалов в стойке для привязки. -oc:tooltip.terminalserver=Компонент, к которому можно подключить беспроводной терминал. Имеет виртуальный экран и клавиатуру. -oc:tooltip.texturepicker=Простой инструмент, позволяющий узнать название текстуры блока, которое можно использовать в 3D печати. -oc:tooltip.tier=§8Уровень %s -oc:tooltip.netsplitter=Работает как переключатель. Соединение каждой стороны переключается ключем. При подаче сигнала красного камня все соединения инвертируются. -oc:tooltip.toolong=Удерживайте [§f%s§7], чтобы отобразить описание. -oc:tooltip.transistor=Базовый элемент для большинства частей компьютера. Он немного деформирован, но отлично выполняет свою работу. -oc:tooltip.transposer=Позволяет автоматизировать перемещение предметов и жидкостей между соседними инвентарями и хранилищами жидкости. -oc:tooltip.upgradeangel=Позволяет роботам размещать блоки в воздухе без точки опоры. -oc:tooltip.upgradebattery=Увеличивает количество энергии, которую робот может хранить, что позволяет ему работать дольше без перезарядки. -oc:tooltip.upgradechunkloader=Если робот движется в лесу и никто его не видит, действительно ли он движется? Данное улучшение гарантирует это. Оно держит чанк, в котором находится робот, загруженным, но постоянно потребляет энергию во время работы. -oc:tooltip.upgradecontainercard=Это улучшение-контейнер позволяет динамически устанавливать и снимать плату с собранного робота. [nl] Максимальный уровень: §f%s§7 -oc:tooltip.upgradecontainerupgrade=Это улучшение-контейнер позволяет динамически устанавливать и снимать другое улучшение с собранного робота. [nl] Максимальный уровень: §f%s§7 -oc:tooltip.upgradecrafting=Позволяет роботам использовать верхнюю левую часть инвентаря для крафта предметов. Вещи должны быть расположены в том же порядке, что и в верстаке. -oc:tooltip.upgradedatabase=Позволяет хранить информацию о предметах для последующего использования другими компонентами.[nl] Поддерживается записей: §f%s§7 -oc:tooltip.upgradeexperience=Это улучшение позволяет роботу накапливать опыт при выполнении различных операций. Чем больше у них опыта, тем больше энергии они могут хранить, могут быстрее собирать блоки и эффективнее использовать инструменты. -oc:tooltip.upgradegenerator=Позволяет роботам генерировать энергию из сжигаемого топлива прямо на ходу.[nl] §fЭффективность§7: §a%s%%§7 -oc:tooltip.upgradehover=Данное улучшение позволяет роботам летать выше над землей без необходимости лазать по стенам.[nl] Максимальная высота: §f%s§7 -oc:tooltip.upgradeinventory=Это улучшение даёт место в инвентаре для робота. Без него роботы не смогут хранить предметы внутри. -oc:tooltip.upgradeinventorycontroller=Это улучшение позволяет роботу контролировать взаимодействие с внешними инвентарями и менять свой экипированный инструмент предметом из его инвентаря. -oc:tooltip.upgradeleash=Позволяет некоторым устройствам, таким как дроны, цеплять животных на поводок. Много животных, при этом. -oc:tooltip.upgrademf=Позволяет адаптерам взаимодействовать с блоками на удалении от них. -oc:tooltip.upgrademf.linked=§fСоединение установлено§7 -oc:tooltip.upgrademf.unlinked=§fНет соединения§7 -oc:tooltip.upgradenavigation=Позволяет определять положение и ориентацию робота. Положение определяется относительно центра карты, использованной при крафте улучшения. -oc:tooltip.upgradepiston=Позволяет двигать блоки, как поршни. §lНе§7 может двигать животных, однако. -oc:tooltip.upgradesign=Позволяет читать и писать текст на табличках. -oc:tooltip.upgradesolargenerator=Позволяет роботам генерировать энергию из солнечного света прямо на ходу. Требует прямую видимость неба над роботом. Генерирует энергию на скорости %s%% от двигателя Стирлинга. -oc:tooltip.upgradetank=Позволяет роботам и дронам взаимодействовать с жидкостями. Без него они не смогут хранить жидкость. -oc:tooltip.upgradetankcontroller=Позволяет роботам и дронам взамодействовать в внешними хранилищами жидкости, а также заливать и выливать жидкости в них. -oc:tooltip.upgradetractorbeam=Даёт роботу самую невероятно продвинутую технологию под кодовым названием "Магнит для предметов". Позволяет роботу подбирать предметы в радиусе 3 блоков от своего расположения. -oc:tooltip.waypoint=Добавляет путевую точку для устройств с навигационным улучшением. -oc:tooltip.wirelessnetworkcard=Позволяет передавать сетевые сообщения по беспроводному каналу в дополнение к проводному. Вы можете настроить §fсилу сигнала§7, чтобы контролировать, насколько далеко должны отправляться сообщения. Более высокая сила сигнала приводит к повышенному потреблению энергии. -oc:tooltip.worldsensorcard=Позволяет получать информацию об атмосфере и гравитации на планетах, добавляемых модом GalactiCraft. Используйте на свой страх и риск. Производитель не несет ответственности за материальный ущерб и увечья. У нас есть адвокаты. И деньги. Даже не пытайтесь. -oc:tooltip.wrench=Гибрид отвертки и ключа. - -#Achievements -achievement.oc.adapter=Мы едины -achievement.oc.adapter.desc=Дайте поработать с другими модами! -achievement.oc.assembler=Великолепно -achievement.oc.assembler.desc=Время захватывать мир! -achievement.oc.cable=Не трогай провода! -achievement.oc.cable.desc=... они от этого ржавеют -achievement.oc.capacitor=Батарея в комплекте -achievement.oc.capacitor.desc=Вы не можете остановить это. -achievement.oc.card=Мы принимаем карточки -achievement.oc.card.desc=Для вашего удобства. Вам это понравится. -achievement.oc.case=В случае возникновения неполадок -achievement.oc.case.desc=Открывайте боковую крышку летом. -achievement.oc.charger=Ладно, сделаем это -achievement.oc.charger.desc=Пошла зарядка.. черт, опять забыл редстоун сигнал. -achievement.oc.chip=Полезные мелочи -achievement.oc.chip.desc=Ведь электронные лампы - прошлый век -achievement.oc.cpu=Разогнанный -achievement.oc.cpu.desc=Время нагрузить его по полной. -achievement.oc.disassembler=Больше не нужно -achievement.oc.disassembler.desc=Когда великолепные идеи оказываются не такими уж и великолепными -achievement.oc.diskDrive=Карусель -achievement.oc.diskDrive.desc=Небольшая емкость, зато какой звук! -achievement.oc.drone=Вездесущее око -achievement.oc.drone.desc=Небольшой брат следит за тобой. -achievement.oc.eeprom=Он может быть только один -achievement.oc.eeprom.desc=Для каждого компьютера, то есть. Для загрузки компьютера, вы знали? -achievement.oc.floppy=Не подносить магнит -achievement.oc.floppy.desc=Дискеты не любят магниты. -achievement.oc.geolyzer=Назад на землю -achievement.oc.geolyzer.desc=Он имеет необычные свойства. -achievement.oc.graphicsCard=Последнее поколение -achievement.oc.graphicsCard.desc=Покажи это. -achievement.oc.hdd=Продавец хотдогов -achievement.oc.hdd.desc=Нет, подождите, это не то, о чем вы подумали. Не роняйте его... -achievement.oc.hologram=Гиперпространство -achievement.oc.hologram.desc=Когда двух измерений уже не хватает -achievement.oc.keyboard=Крошкохранитель-3000 -achievement.oc.keyboard.desc=Не рекомендуется переворачивать и трясти его -achievement.oc.microcontroller=Маленькая сестренка -achievement.oc.microcontroller.desc=Просто маленький компьютер -achievement.oc.motionSensor=Оно двигается -achievement.oc.motionSensor.desc=Как Майкл Джексон. -achievement.oc.networkCard=Нам надо поговорить! -achievement.oc.networkCard.desc=Оставайтесь на связи с дальними родственниками. -achievement.oc.openOS=Поехали -achievement.oc.openOS.desc=Неужели он включится. -achievement.oc.powerDistributor=Поделись с ближним -achievement.oc.powerDistributor.desc=Когда вы помогаете распределять энергию. -achievement.oc.rack=Прямо в стойку -achievement.oc.rack.desc=Не знаю, о чем думаете вы, я думал о серверной стойке. -achievement.oc.raid=Чрезмерная избыточность -achievement.oc.raid.desc=Только диски не вынимайте. -achievement.oc.ram=Случайный доступ к памяти -achievement.oc.ram.desc=Поздравляем, вы делаете это правильно. -achievement.oc.redstoneCard=Есть контакт -achievement.oc.redstoneCard.desc=Возврат к аналоговой технике. -achievement.oc.redstoneIO=Выскочка -achievement.oc.redstoneIO.desc=Когда все сигналы в нужных местах -achievement.oc.robot=Бип-пип -achievement.oc.robot.desc=УНИЧТОЖИТЬ! -achievement.oc.screen=Вы пробовали выключить и снова включить? -achievement.oc.screen.desc=Серьезно. Редстоун сигнал может выключать монитор. -achievement.oc.server=Выделенный сервер -achievement.oc.server.desc=Облачные вычисления, мы идем к вам. -achievement.oc.switch=Сложная топология -achievement.oc.switch.desc=Избегайте сложных связей и потери пакетов. -achievement.oc.tablet=Несъедобно -achievement.oc.tablet.desc=Держите подальше от маленьких детей, во избежание пропажи денег на вашей кредитной карте. -achievement.oc.transistor=Редстоун, скажи "Привет." -achievement.oc.transistor.desc=Создайте транзистор. Потом послушайте музыку. Не благодарите меня. -achievement.oc.wirelessNetworkCard=Сигналы -achievement.oc.wirelessNetworkCard.desc=Время идти туда, где никогда не появлялся сигнал. - -# Death messages. Note that the number of entries here must match the number -# set in the actual damage source in code. -death.attack.oc.nanomachinesOverload.1=%s был слишком жадным. -death.attack.oc.nanomachinesOverload.2=%s получил нервный срыв. -death.attack.oc.nanomachinesOverload.3=Нанороботы %s вышли из под контроля. -death.attack.oc.nanomachinesHungry.1=%s был съеден нанороботами. -death.attack.oc.nanomachinesHungry.2=%s не кормил нанороботов. -death.attack.oc.nanomachinesHungry.3=%s был переварен нанороботами. - -# NEI Integration -nei.options.inventory.oredict=Показывать имена Ore Dictionary -nei.options.inventory.oredict.true=Да -nei.options.inventory.oredict.false=Нет -nei.usage.oc.Manual=Открыть руководство - -# Waila Integration -option.oc.address=Адрес -option.oc.componentName=Название компонента -option.oc.energy=Энергия diff --git a/src/main/resources/assets/opencomputers/lang/ru_ru.json b/src/main/resources/assets/opencomputers/lang/ru_ru.json new file mode 100644 index 0000000000..1cee1964b2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/ru_ru.json @@ -0,0 +1,457 @@ +{ + "tile.oc.accesspoint": "§cТочка доступа§7", + "tile.oc.adapter": "Адаптер", + "tile.oc.assembler": "Сборщик", + "tile.oc.cable": "Кабель", + "tile.oc.capacitor": "Конденсатор энергии", + "tile.oc.case1": "Системный блок (1-ый уровень)", + "tile.oc.case2": "Системный блок (2-ой уровень)", + "tile.oc.case3": "Системный блок (3-ий уровень)", + "tile.oc.casecreative": "Системный блок (Творческий)", + "tile.oc.chameliumblock": "Блок хамелиума", + "tile.oc.charger": "Зарядное устройство", + "tile.oc.disassembler": "Разборщик", + "tile.oc.diskdrive": "Дисковод", + "tile.oc.endstone": "Камень края", + "tile.oc.geolyzer": "Геоанализатор", + "tile.oc.hologram1": "Голографический проектор (1-ый уровень)", + "tile.oc.hologram2": "Голографический проектор (2-ой уровень)", + "tile.oc.keyboard": "Клавиатура", + "tile.oc.microcontroller": "Микроконтроллер", + "tile.oc.motionsensor": "Датчик движения", + "tile.oc.netsplitter": "Сетевой переключатель", + "tile.oc.powerconverter": "Преобразователь энергии", + "tile.oc.powerdistributor": "Распределитель энергии", + "tile.oc.print": "3D модель", + "tile.oc.printer": "3D принтер", + "tile.oc.raid": "RAID", + "tile.oc.redstone": "Красный контроллер", + "tile.oc.relay": "Ретранслятор", + "tile.oc.robot": "Робот", + "tile.oc.robotafterimage": "Робот", + "tile.oc.screen1": "Монитор (1-ый уровень)", + "tile.oc.screen2": "Монитор (2-ой уровень)", + "tile.oc.screen3": "Монитор (3-ий уровень)", + "tile.oc.rack": "Серверная стойка", + "tile.oc.switch": "§cКоммутатор§7", + "tile.oc.transposer": "Транспозер", + "tile.oc.waypoint": "Путевая точка", + "item.oc.abstractbuscard": "Карта абстрактной шины", + "item.oc.acid": "Кислота", + "item.oc.alu": "Арифметико-логическое устройство (АЛУ)", + "item.oc.analyzer": "Анализатор", + "item.oc.apu0": "Процессор с видеокартой (APU) (1-ый уровень)", + "item.oc.apu1": "Процессор с видеокартой (APU) (2-ой уровень)", + "item.oc.apu2": "Процессор с видеокартой (APU) (Творческий)", + "item.oc.arrowkeys": "Клавиши со стрелками", + "item.oc.buttongroup": "Группа кнопок", + "item.oc.cardbase": "Основа для карт", + "item.oc.chamelium": "Хамелиум", + "item.oc.circuitboard": "Нетравленая печатная плата", + "item.oc.componentbus0": "Компонентная шина (1-ый уровень)", + "item.oc.componentbus1": "Компонентная шина (2-ой уровень)", + "item.oc.componentbus2": "Компонентная шина (3-ий уровень)", + "item.oc.controlunit": "Устройство управления (УУ)", + "item.oc.cpu0": "Центральный процессор (ЦП) (1-ый уровень)", + "item.oc.cpu1": "Центральный процессор (ЦП) (2-ой уровень)", + "item.oc.cpu2": "Центральный процессор (ЦП) (3-ий уровень)", + "item.oc.cuttingwire": "Проволока", + "item.oc.datacard0": "Карта данных (1-ый уровень)", + "item.oc.datacard1": "Карта данных (2-ой уровень)", + "item.oc.datacard2": "Карта данных (3-ий уровень)", + "item.oc.debugcard": "Отладочная карта", + "item.oc.debugger": "Сетевой отладчик", + "item.oc.diamondchip": "Алмазный обломок", + "item.oc.disk": "Металлический диск", + "item.oc.diskdrivemountable": "Дисковод (для серверной стойки)", + "item.oc.drone": "Дрон", + "item.oc.dronecase0": "Корпус дрона (1-ый уровень)", + "item.oc.dronecase1": "Корпус дрона (2-ой уровень)", + "item.oc.dronecase3": "Корпус дрона (Креатив)", + "item.oc.eeprom": "EEPROM", + "item.oc.floppydisk": "Дискета", + "item.oc.graphicscard0": "Видеокарта (1-ый уровень)", + "item.oc.graphicscard1": "Видеокарта (2-ой уровень)", + "item.oc.graphicscard2": "Видеокарта (3-ий уровень)", + "item.oc.harddiskdrive0": "Жёсткий диск (1-ый уровень)", + "item.oc.harddiskdrive1": "Жёсткий диск (2-ой уровень)", + "item.oc.harddiskdrive2": "Жёсткий диск (3-ий уровень)", + "item.oc.hoverboots": "Парящие ботинки", + "item.oc.inkcartridge": "Картридж с чернилами", + "item.oc.inkcartridgeempty": "Картридж с чернилами (Пустой)", + "item.oc.internetcard": "Интернет карта", + "item.oc.interweb": "Интерпаутина", + "item.oc.ironnugget": "Железный самородок", + "item.oc.linkedcard": "Соединённая карта", + "item.oc.manual": "Руководство OpenComputers", + "item.oc.memory0": "Память (1-ый уровень)", + "item.oc.memory1": "Память (Уровень 1.5)", + "item.oc.memory2": "Память (2-ой уровень)", + "item.oc.memory3": "Память (Уровень 2.5)", + "item.oc.memory4": "Память (3-ий уровень)", + "item.oc.memory5": "Память (Уровень 3.5)", + "item.oc.microchip0": "Микрочип (1-ый уровень)", + "item.oc.microchip1": "Микрочип (2-ой уровень)", + "item.oc.microchip2": "Микрочип (3-ий уровень)", + "item.oc.microcontrollercase0": "Корпус микроконтроллера (1-ый уровень)", + "item.oc.microcontrollercase1": "Корпус микроконтроллера (2-ой уровень)", + "item.oc.microcontrollercase3": "Корпус микроконтроллера (Креатив)", + "item.oc.nanomachines": "Нанороботы", + "item.oc.networkcard": "Сетевая карта", + "item.oc.numpad": "Цифровой блок клавиш", + "item.oc.present": "Маленькое что-то...", + "item.oc.printedcircuitboard": "Печатная плата", + "item.oc.rawcircuitboard": "Основа для печатной платы", + "item.oc.redstonecard0": "Плата на красном камне (1-ый уровень)", + "item.oc.redstonecard1": "Плата на красном камне (2-ой уровень)", + "item.oc.server0": "Сервер (1-ый уровень)", + "item.oc.server1": "Сервер (2-ой уровень)", + "item.oc.server2": "Сервер (3-ий уровень)", + "item.oc.server3": "Сервер (Творческий)", + "item.oc.tablet": "Планшет", + "item.oc.tabletcase0": "Корпус планшета (1-ый уровень)", + "item.oc.tabletcase1": "Корпус планшета (2-ой уровень)", + "item.oc.tabletcase3": "Корпус планшета (Креатив)", + "item.oc.terminal": "Беспроводной терминал", + "item.oc.terminalserver": "Терминальный сервер", + "item.oc.texturepicker": "Определитель текстур", + "item.oc.transistor": "Транзистор", + "item.oc.upgradeangel": "\"Ангельское\" улучшение", + "item.oc.upgradebattery0": "Улучшение \"Ёмкость\" (1-ый уровень)", + "item.oc.upgradebattery1": "Улучшение \"Ёмкость\" (2-ой уровень)", + "item.oc.upgradebattery2": "Улучшение \"Ёмкость\" (3-ий уровень)", + "item.oc.upgradechunkloader": "Улучшение \"Загрузчик чанков\"", + "item.oc.upgradecontainercard0": "Контейнер для карты (1-ый уровень)", + "item.oc.upgradecontainercard1": "Контейнер для карты (2-ой уровень)", + "item.oc.upgradecontainercard2": "Контейнер для карты (3-ий уровень)", + "item.oc.upgradecontainerupgrade0": "Контейнер для улучшения (1-ый уровень)", + "item.oc.upgradecontainerupgrade1": "Контейнер для улучшения (2-ой уровень)", + "item.oc.upgradecontainerupgrade2": "Контейнер для улучшения (3-ий уровень)", + "item.oc.upgradecrafting": "Улучшение \"Верстак\"", + "item.oc.upgradedatabase0": "Улучшение \"База данных\" (1-ый уровень)", + "item.oc.upgradedatabase1": "Улучшение \"База данных\" (2-ой уровень)", + "item.oc.upgradedatabase2": "Улучшение \"База данных\" (3-ий уровень)", + "item.oc.upgradeexperience": "Улучшение \"Опыт\"", + "item.oc.upgradegenerator": "Улучшение \"Генератор\"", + "item.oc.upgradehover0": "Улучшение \"Парение\" (1-ый уровень)", + "item.oc.upgradehover1": "Улучшение \"Парение\" (2-ый уровень)", + "item.oc.upgradeinventory": "Улучшение \"Инвентарь\"", + "item.oc.upgradeinventorycontroller": "Улучшение \"Контроллер инвентаря\"", + "item.oc.upgradeleash": "Улучшение \"Поводок\"", + "item.oc.upgrademf": "МФУ", + "item.oc.upgradenavigation": "Улучшение \"Навигация\"", + "item.oc.upgradepiston": "Улучшение \"Поршень\"", + "item.oc.upgradesign": "Улучшение \"Контроллер табличек\"", + "item.oc.upgradesolargenerator": "Улучшение \"Солнечный генератор\"", + "item.oc.upgradetank": "Улучшение \"Бак для жидкостей\"", + "item.oc.upgradetankcontroller": "Улучшение \"Контроллер бака\"", + "item.oc.upgradetractorbeam": "Улучшение \"Притягивающий луч\"", + "item.oc.upgradetrading": "Улучшение \"Торговля\"", + "item.oc.wirelessnetworkcard0": "Плата беспроводной сети (1-ый уровень)", + "item.oc.wirelessnetworkcard1": "Плата беспроводной сети (2-ой уровень)", + "item.oc.worldsensorcard": "Карта-мировой сенсор", + "item.oc.wrench": "Ключ", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.Drone": "Дрон", + "oc:gui.Analyzer.Address": "§6Адрес§f: %s", + "oc:gui.Analyzer.AddressCopied": "Адрес скопирован в буфер обмена.", + "oc:gui.Analyzer.ChargerSpeed": "§6Скорость зарядки§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Имя компонента§f: %s", + "oc:gui.Analyzer.Components": "§6Количество подключенных компонентов§f: %s", + "oc:gui.Analyzer.CopyToClipboard": "Кликните для копирования в буфер обмена.", + "oc:gui.Analyzer.LastError": "§6Последняя ошибка§f: %s", + "oc:gui.Analyzer.RobotName": "§6Имя§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Владелец§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Опыт§f: %s (Уровень: %s)", + "oc:gui.Analyzer.StoredEnergy": "§6Накоплено энергии§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Всего накоплено энергии§f: %s", + "oc:gui.Analyzer.Users": "§6Пользователи§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6Уровень сигнала§f: %s", + "oc:gui.Assembler.Collect": "Заберите результат сборки", + "oc:gui.Assembler.Complexity": "Сложность: %s/%s", + "oc:gui.Assembler.InsertCase": "Вставьте системный блок", + "oc:gui.Assembler.InsertCPU": "Вставьте процессор", + "oc:gui.Assembler.InsertRAM": "Вставьте память", + "oc:gui.Assembler.Progress": "Прогресс: %s%% (%s)", + "oc:gui.Assembler.Run": "Собрать", + "oc:gui.Assembler.Warning.BIOS": "BIOS", + "oc:gui.Assembler.Warning.GraphicsCard": "Видеокарта", + "oc:gui.Assembler.Warning.Inventory": "Улучшение \"Инвентарь\"", + "oc:gui.Assembler.Warning.Keyboard": "Клавиатура", + "oc:gui.Assembler.Warning.OS": "Загрузочный диск", + "oc:gui.Assembler.Warning.Screen": "Монитор", + "oc:gui.Assembler.Warnings": "§eВнимание§7: Отсутствуют рекомендуемые компоненты.", + "oc:gui.Chat.NewVersion": "Доступна новая версия: %s", + "oc:gui.Chat.TextureName": "§7Имя текстуры: §a%s§f.", + "oc:gui.Chat.WarningClassTransformer": "Возникли §cошибки§f при преобразовании классов. Пожалуйста, сообщите об этом, а также приложите файл FML §alatest.log§f/§afml-server-latest.log§f!", + "oc:gui.Chat.WarningFingerprint": "§cВНИМАНИЕ§f - несовпадение отпечатка файла! Ожидаемый: '§a%s§f', полученный: '§e%s§f'. Если Вы не разработчик, использующий деобфусцированную версию мода, то §lкрайне§f желательно заново скачать OpenComputers, поскольку JAR-файл, возможно, был изменён.", + "oc:gui.Chat.WarningLink": "Невозможно открыть ссылку: %s", + "oc:gui.Chat.WarningLuaFallback": "Исходные библиотеки Lua не доступны, компьютеры не смогут сохранять своё состояние. Они перезагрузятся после выгрузки чанка.", + "oc:gui.Chat.WarningProjectRed": "Вы используете версию Project: Red, несовместимую с OpenComputers. Попробуйте обновить Project: Red.", + "oc:gui.Chat.WarningRecipes": "Произошла ошибка при загрузке одного или нескольких рецептов. Некоторые предметы могут не крафтиться. Проверьте логи, чобы узнать подробнее.", + "oc:gui.Drive.Managed": "Файловый режим", + "oc:gui.Drive.Unmanaged": "Блочный режим", + "oc:gui.Drive.Warning": "§lВнимание§r: переключение режимов очищает диск!", + "oc:gui.Error.ComponentOverflow": "Слишком много компонентов подключено к компьютеру.", + "oc:gui.Error.InternalError": "Возникла внутренняя ошибка, пожалуйста, посмотрите лог-файл. Возможно, это баг.", + "oc:gui.Error.NoCPU": "Не установлен процессор.", + "oc:gui.Error.NoEnergy": "Недостаточно энергии.", + "oc:gui.Error.NoRAM": "Не установлена память.", + "oc:gui.Error.OutOfMemory": "Недостаточно памяти.", + "oc:gui.Manual.Blocks": "Блоки OpenComputers", + "oc:gui.Manual.Home": "Главная страница", + "oc:gui.Manual.Items": "Предметы OpenComputers", + "oc:gui.Manual.Warning.BlockMissing": "Блок недоступен.", + "oc:gui.Manual.Warning.ImageMissing": "Изображение не найдено.", + "oc:gui.Manual.Warning.ItemMissing": "Предмет недоступен.", + "oc:gui.Manual.Warning.OreDictMissing": "Запись Ore Dictionary недоступна.", + "oc:gui.Raid.Warning": "§4Добавление диска очистит его.\nУдаление диска очистит RAID.", + "oc:gui.Robot.Power": "Энергия", + "oc:gui.Robot.TurnOff": "Выключить", + "oc:gui.Robot.TurnOn": "Включить", + "oc:gui.Rack.Back": "Сзади", + "oc:gui.Rack.Bottom": "Снизу", + "oc:gui.Rack.Left": "Слева", + "oc:gui.Rack.None": "Нет", + "oc:gui.Rack.Right": "Справа", + "oc:gui.Rack.Enabled": "Включено", + "oc:gui.Rack.Disabled": "Выключено", + "oc:gui.Rack.Top": "Сверху", + "oc:gui.Switch.TransferRate": "Цикличность", + "oc:gui.Switch.PacketsPerCycle": "Пакеты / цикл", + "oc:gui.Switch.QueueSize": "Размер очереди", + "oc:gui.Terminal.InvalidKey": "Неверный ключ, скорее всего, к серверу уже подключен другой терминал.", + "oc:gui.Terminal.OutOfRange": "Нет сигнала.", + "oc:container.accesspoint": "Точка доступа", + "oc:container.adapter": "Адаптер", + "oc:container.case": "Компьютер", + "oc:container.charger": "Зарядное устройство", + "oc:container.disassembler": "Разборщик", + "oc:container.diskdrive": "Дисковод", + "oc:container.printer": "Принтер", + "oc:container.raid": "RAID", + "oc:container.relay": "Ретранслятор", + "oc:container.server": "Сервер", + "oc:container.rack": "Серверная стойка", + "oc:container.switch": "Коммутатор", + "oc:container.tabletwrapper": "Планшет", + "key.opencomputers.clipboardPaste": "Вставить из буфера обмена", + "key.opencomputers.materialCosts": "Показать стоимость в материалах", + "oc:tooltip.accesspoint": "Работает как коммутатор, но и с беспроводными сетями.", + "oc:tooltip.abstractbuscard": "Обеспечивает взаимодействие с абстрактной шиной из §fStargateTech 2§7 (отправка и приём LIP-пакетов).", + "oc:tooltip.acid": "Высокотоксичная псевдо-жидкость, которую обычно пьют только определённые пираты. Однако может быть полезна и при других применениях.", + "oc:tooltip.adapter": "Используется для контроля некомпонентных блоков, таких как обычные блоки или блоки из других модов.", + "oc:tooltip.alu": "Выполняет арифметические вычисления, так что вам не придётся возиться с ними.", + "oc:tooltip.analyzer": "Используется для отображения информации о блоках, такой как §fадрес§7 или §fимя компонента§7.\nТакже отображает ошибку, вызвавшую сбой компьютера.", + "oc:tooltip.apu": "Это процессор со встроенной видеокартой, полезный, когда вам требуется освободить ещё один слот для карт.\nПоддерживается компонентов: §f%s§7\nМаксимальное разрешение: §f%sx%s§7\nМаксимальная глубина цвета: §f%s§7\nОпераций в тик: §f%s§7", + "oc:tooltip.assembler": "Позволяет собирать роботов и другие устройства из ряда различных частей компьютера.", + "oc:tooltip.cable": "Простой и дешёвый способ соединить компоненты между собой.", + "oc:tooltip.capacitor": "Накапливает энергию для дальнейшего использования. Может быть очень быстро заполнен и опустошён.", + "oc:tooltip.cardbase": "Как видно из названия, это основа для всех карт расширения.", + "oc:tooltip.case": "Системный блок - основа компьютера, содержащий §fкарты расширения§7, §fОЗУ§7 и §fжёсткие диски§7.\nСлотов: §f%s§7", + "oc:tooltip.chamelium": "Базовый материал для 3D печати. Не глотать: может привести к слепоте и временным отсутствием присутствия.", + "oc:tooltip.chameliumblock": "Удобен для окрашенных 3D моделей или просто как цветной блок для вашей базы.", + "oc:tooltip.charger": "Передаёт энергию из аккумуляторов вплотную находящимся роботам и дронам. Скорость передачи зависит от §fсилы сигнала красного камня§7: отсутствие сигнала означает \"не заряжать\", а полный сигнал - \"заряжать на полной скорости\".", + "oc:tooltip.circuitboard": "Мы уже очень близки. Может быть вытравлена, чтобы получить печатную плату.", + "oc:tooltip.controlunit": "Это штука, которая... контролирует... что-то. Она необходима, чтобы создать центральный процессор. Так что, да, она очень важна.", + "oc:tooltip.componentbus": "Позволяет серверам взаимодействовать с большим количеством компонентов.\nПоддерживается компонентов: §f%s§7", + "oc:tooltip.cpu": "Является важным компонентом в компьютере. Тактовая частота немного нестабильна, но что вы ожидали, если он работает на карманных солнечных часах. Количество поддерживаемых компонентов: §f%s§7", + "oc:tooltip.cpu.architecture": "Архитектура: §f%s§7", + "oc:tooltip.cuttingwire": "Используется для нарезки глиняных блоков в пластины. Рвётся после использования, что делает её, пожалуй, самым неэффективным инструментом.", + "oc:tooltip.datacard0": "Обеспечивает поддержку нескольких продвинутых алгоритмов, таких как хеширование и сжатие.", + "oc:tooltip.datacard1": "Обеспечивает поддержку нескольких продвинутых алгоритмов, таких как AES-шифрование, хеширование и сжатие.", + "oc:tooltip.datacard2": "Обеспечивает поддержку нескольких продвинутых алгоритмов, таких как AES-шифрование, эллиптическая криптография, хеширование и сжатие.", + "oc:tooltip.debugcard": "Креативный предмет, позволяет манипулировать игровым миром. Используйте на свой страх и риск.", + "oc:tooltip.debugger": "Может быть использован для вывода отладочной информации о внутренней сети. Используйте только тогда, когда попросил разработчик.", + "oc:tooltip.diamondchip": "Небольшой кусочек некогда сияющего алмаза. Он больше никогда не будет таким, как прежде.", + "oc:tooltip.disassembler": "Разделяет предметы на исходные компоненты. §lВнимание§7: возвращённые предметы имеют шанс %s%% сломаться!", + "oc:tooltip.disk": "Примитивный носитель, который может быть использован для создания постоянных запоминающих устройств.", + "oc:tooltip.diskdrive.cc": "§aПоддерживаются§7 дискеты из ComputerCraft.", + "oc:tooltip.diskdrive": "Позволяет читать и записывать дискеты. Может быть установлен в роботов, что позволит затем вставлять дискеты.", + "oc:tooltip.diskdrivemountable": "Работает так же, как и обычный дисковод, но может быть вставлен только в серверную стойку.", + "oc:tooltip.diskusage": "Занято %s/%s байт", + "oc:tooltip.diskmodemanaged": "Режим: файловый", + "oc:tooltip.diskmodeunmanaged": "Режим: блочный", + "oc:tooltip.drone": "Дроны это легкие и быстрые устройства, но с ограниченным инвентарем.", + "oc:tooltip.dronecase": "Корпус, предназначенный для создания дрона в сборщике. Вмещает малое количество компонентов и предоставляет левитацию с помощью силы камня края.", + "oc:tooltip.eeprom": "Маленькое программируемое хранилище, которое содержит BIOS для запуска компьютеров.", + "oc:tooltip.fakeendstone": "Почти такой же, как и настоящий камень края, даже эмулирует его легкость!", + "oc:tooltip.geolyzer": "Позволяет сканировать твёрдость блоков в окрестности. Эта информация может быть полезна для создания голограммы области или для обнаружения руд.", + "oc:tooltip.graphicscard": "Используется для изменения того, что отображается на мониторах.\nМаксимальное разрешение: §f%sx%s§7\nМаксимальная глубина цвета:§f%s§7\nОпераций/такт: §f%s§7", + "oc:tooltip.hoverboots": "Прыгайте выше, падайте глубже, бегайте быстрее. Это и многое другое с нашими новыми Парящими ботинками (TM).", + "oc:tooltip.inkcartridge": "Используется в 3D печати. По таинственным причинам ему не нужно оставаться в принтере.", + "oc:tooltip.inkcartridgeempty": "Этот картридж выглядит пустым. Заправьте его с помощью красителей. Или выбросьте.", + "oc:tooltip.internetcard": "Эта карта позволяет делать HTTP-запросы и использовать реальные TCP сокеты.", + "oc:tooltip.interweb": "Поздравляем, вы выиграли одну (1) интерсеть. Подключиться к ней можно с помощью Интернет-платы. Осторожно: не кормите троллей.", + "oc:tooltip.ironnugget": "Самородок, созданный из железа. Может, именно поэтому он и назван железным самородком? Хм...", + "oc:tooltip.keyboard": "Присоединяется к монитору, позволяя вводить информацию.", + "oc:tooltip.hologram0": "Объёмный дисплей, управляемый компьютером и использующийся для отображения произвольных воксельных структур.\nРазрешение: §f48x32x48§7\nМаксимальный масштаб: §f3x§7\nГлубина цвета: §fМонохромный§7", + "oc:tooltip.hologram1": "Объёмный дисплей, управляемый компьютером и использующийся для отображения произвольных воксельных структур.\nРазрешение: §f48x32x48§7\nМаксимальный масштаб: §f4x§7\nГлубина цвета: §fТрёхцветный§7", + "oc:tooltip.linkedcard": "Они изготавливаются в парах и могут общаться только с партнёром. Тем не менее, общаться они могут на любом расстоянии - даже между измерениями. Однако для отправки сообщения нужно довольно много энергии.", + "oc:tooltip.linkedcard_channel": "§8Канал: %s§7", + "oc:tooltip.manual": "Содержит всю информацию о моде OpenComputers, которая вам может когда-либо понадобиться. И даже больше. По невероятно низкой цене... §oнажмите R для продолжения§7.", + "oc:tooltip.materialcosts": "Удерживайте [§f%s§7] для показа материалов.", + "oc:tooltip.materials": "Материалы:", + "oc:tooltip.memory": "Необходима для запуска компьютера. Чем больше ОЗУ, тем более требовательные программы Вы можете запустить.", + "oc:tooltip.microchip": "Чип, ранее известный как интегральная схема. Понятия не имею почему, но он работает с красным камнем.", + "oc:tooltip.microcontroller": "Микроконтроллеры - это компьютеры, сведённые к самым базовым вещам. Они используются для выполнения специфических задач и выполняют программу, записанную на EEPROM.\n§cНе могут взаимодействовать с внешними компонентами.§7", + "oc:tooltip.microcontrollercase": "Базовый компонент для создания микроконтроллеров. Положите в сборщик, чтобы установить компоненты, и соберите микроконтроллер.", + "oc:tooltip.motionsensor": "Может обнаружить движение ближайших живых существ. Требуется прямая линия видимости.", + "oc:tooltip.nanomachines": "Блок управления и кучка нанороботов для приема внутрь, если вы решились.", + "oc:tooltip.networkcard": "Позволяет обмениваться сообщениями между соединённым друг с другом - с помощью кабеля или других блоков - компьютерами.", + "oc:tooltip.poweracceptor": "Скорость преобразования энергии: §f%s/t§7", + "oc:tooltip.powerconverter.buildcraft": "§fBuildCraft MJ§7: §a%s:%s§7", + "oc:tooltip.powerconverter.factorization": "§fFactorization Charge§7: §a%s:%s§7", + "oc:tooltip.powerconverter.industrialcraft2": "§fIndustrialCraft² EU§7: §a%s:%s§7", + "oc:tooltip.powerconverter.mekanism": "§fMekanism Joules§7: §a%s:%s§7", + "oc:tooltip.powerconverter.thermalexpansion": "§fThermal Expansion RF§7: §a%s:%s§7", + "oc:tooltip.powerconverter.resonantengine": "§fResonant Engine Coulombs§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Преобразует энергию из других модов во внутренний тип энергии. Соотношение энергии:", + "oc:tooltip.powerdistributor": "Передаёт энергию между различными сетями. Полезно, если требуется запитать от одного преобразователя несколько сетей, которые должны оставаться разделёнными.", + "oc:tooltip.present": "Откройте этот подарок, чтобы получить немного §kчего-то§7!\n§8Крафтите предметы OpenComputers в нужное время, чтобы получить шанс получить подарок.§7", + "oc:tooltip.print.beaconbase": "§8Используется в качестве основы для маяка.", + "oc:tooltip.print.lightvalue": "§8Сила излучаемого света: %s.", + "oc:tooltip.print.redstonelevel": "§8Сила выдаваемого красного сигнала: %s.", + "oc:tooltip.printedcircuitboard": "Основа плат, памяти и прочего.", + "oc:tooltip.printer": "Позволяет печатать пользовательские 3D-модели, используя хамелиум и картриджи с чернилами. Должен быть настроен с помощью компьютера. Держите подальше от детей.", + "oc:tooltip.raid": "Позволяет соединять три жестких диска в единую файловую систему, которую могут использовать все подключенные компьютеры.", + "oc:tooltip.rawcircuitboard": "Может быть закалена в печи для получения печатной платы.", + "oc:tooltip.redstone": "Позволяет считывать и подавать сигналы красного камня вокруг блока. Контролируется любым подключенным компьютером. Иными словами, это что-то вроде внешней платы на красном камне.", + "oc:tooltip.redstonecard.projectred": "Мод §fProjectRed§7 §aподдерживается§7.", + "oc:tooltip.redstonecard.redlogic": "Мод §fRedLogic§7 §aподдерживается§7.", + "oc:tooltip.redstonecard.rednet": "Мод §fRedNet§7 §aподдерживается§7.", + "oc:tooltip.redstonecard.wirelesscbe": "Мод §fWireless Redstone (ChickenBones)§7 §aподдерживается§7.", + "oc:tooltip.redstonecard.wirelesssv": "Мод §fWireless Redstone (SlimeVoid)§7 §aподдерживается§7.", + "oc:tooltip.redstonecard": "Позволяет считывать и подавать сигналы красного камня вокруг компьютера или робота.", + "oc:tooltip.relay": "Позволяет соединять различные сети между собой. Передаются только сообщения, компоненты между сетями не будут доступны. Используйте его для разделения сетей с возможностью пересылать сообщения между ними.", + "oc:tooltip.robot": "В отличие от компьютеров, роботы могут передвигаться и взаимодействовать с миром, как игрок.\n§cНе могут подключаться к внешним компонентам.§7", + "oc:tooltip.robot_level": "§fУровень§7: §a%s§7.", + "oc:tooltip.robot_storedenergy": "§fНакопленная энергия§7: §a%s§7.", + "oc:tooltip.screen": "Отображает текст, передаваемый видеокартой.\nМаксимальное разрешение: §f%sx%s§7\nМаксимальная глубина цвета: §f%s§7", + "oc:tooltip.server": "Это сервер. Есть много других, похожих на него, но только этот может быть улучшен компонентами, как системный блок. Можно включить после размещения в серверную стойку.", + "oc:tooltip.server.components": "Установленные компоненты:", + "oc:tooltip.rack": "Обеспечивает работу до четырёх серверов или других монтируемых компонентов.", + "oc:tooltip.switch": "Позволяет соединять различные сети между собой. Передаются только сообщения, компоненты между сетями не будут доступны. Используйте его для разделения сетей с возможностью пересылать сообщения между ними.", + "oc:tooltip.tablet": "Планшет, полностью готовый к работе с Lua. Может быть отключен нажатием правой кнопки мыши + Shift.", + "oc:tooltip.tabletcase": "Простой корпус для планшета. Поместите в сборщик, чтобы вставить компоненты, и соберите себе планшетный компьютер.", + "oc:tooltip.terminal": "Позволяет дистанционно управлять сервером, пока вы находитесь в радиусе его действия. Действует как портативный дисплей с клавиатурой.\nShift+ПКМ по серверу терминалов в стойке для привязки.", + "oc:tooltip.terminalserver": "Компонент, к которому можно подключить беспроводной терминал. Имеет виртуальный экран и клавиатуру.", + "oc:tooltip.texturepicker": "Простой инструмент, позволяющий узнать название текстуры блока, которое можно использовать в 3D печати.", + "oc:tooltip.tier": "§8Уровень %s", + "oc:tooltip.netsplitter": "Работает как переключатель. Соединение каждой стороны переключается ключем. При подаче сигнала красного камня все соединения инвертируются.", + "oc:tooltip.toolong": "Удерживайте [§f%s§7], чтобы отобразить описание.", + "oc:tooltip.transistor": "Базовый элемент для большинства частей компьютера. Он немного деформирован, но отлично выполняет свою работу.", + "oc:tooltip.transposer": "Позволяет автоматизировать перемещение предметов и жидкостей между соседними инвентарями и хранилищами жидкости.", + "oc:tooltip.upgradeangel": "Позволяет роботам размещать блоки в воздухе без точки опоры.", + "oc:tooltip.upgradebattery": "Увеличивает количество энергии, которую робот может хранить, что позволяет ему работать дольше без перезарядки.", + "oc:tooltip.upgradechunkloader": "Если робот движется в лесу и никто его не видит, действительно ли он движется? Данное улучшение гарантирует это. Оно держит чанк, в котором находится робот, загруженным, но постоянно потребляет энергию во время работы.", + "oc:tooltip.upgradecontainercard": "Это улучшение-контейнер позволяет динамически устанавливать и снимать плату с собранного робота.\nМаксимальный уровень: §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "Это улучшение-контейнер позволяет динамически устанавливать и снимать другое улучшение с собранного робота.\nМаксимальный уровень: §f%s§7", + "oc:tooltip.upgradecrafting": "Позволяет роботам использовать верхнюю левую часть инвентаря для крафта предметов. Вещи должны быть расположены в том же порядке, что и в верстаке.", + "oc:tooltip.upgradedatabase": "Позволяет хранить информацию о предметах для последующего использования другими компонентами.\nПоддерживается записей: §f%s§7", + "oc:tooltip.upgradeexperience": "Это улучшение позволяет роботу накапливать опыт при выполнении различных операций. Чем больше у них опыта, тем больше энергии они могут хранить, могут быстрее собирать блоки и эффективнее использовать инструменты.", + "oc:tooltip.upgradegenerator": "Позволяет роботам генерировать энергию из сжигаемого топлива прямо на ходу.\n§fЭффективность§7: §a%s%%§7", + "oc:tooltip.upgradehover": "Данное улучшение позволяет роботам летать выше над землей без необходимости лазать по стенам.\nМаксимальная высота: §f%s§7", + "oc:tooltip.upgradeinventory": "Это улучшение даёт место в инвентаре для робота. Без него роботы не смогут хранить предметы внутри.", + "oc:tooltip.upgradeinventorycontroller": "Это улучшение позволяет роботу контролировать взаимодействие с внешними инвентарями и менять свой экипированный инструмент предметом из его инвентаря.", + "oc:tooltip.upgradeleash": "Позволяет некоторым устройствам, таким как дроны, цеплять животных на поводок. Много животных, при этом.", + "oc:tooltip.upgrademf": "Позволяет адаптерам взаимодействовать с блоками на удалении от них.", + "oc:tooltip.upgrademf.linked": "§fСоединение установлено§7", + "oc:tooltip.upgrademf.unlinked": "§fНет соединения§7", + "oc:tooltip.upgradenavigation": "Позволяет определять положение и ориентацию робота. Положение определяется относительно центра карты, использованной при крафте улучшения.", + "oc:tooltip.upgradepiston": "Позволяет двигать блоки, как поршни. §lНе§7 может двигать животных, однако.", + "oc:tooltip.upgradesign": "Позволяет читать и писать текст на табличках.", + "oc:tooltip.upgradesolargenerator": "Позволяет роботам генерировать энергию из солнечного света прямо на ходу. Требует прямую видимость неба над роботом. Генерирует энергию на скорости %s%% от двигателя Стирлинга.", + "oc:tooltip.upgradetank": "Позволяет роботам и дронам взаимодействовать с жидкостями. Без него они не смогут хранить жидкость.", + "oc:tooltip.upgradetankcontroller": "Позволяет роботам и дронам взамодействовать в внешними хранилищами жидкости, а также заливать и выливать жидкости в них.", + "oc:tooltip.upgradetractorbeam": "Даёт роботу самую невероятно продвинутую технологию под кодовым названием \"Магнит для предметов\". Позволяет роботу подбирать предметы в радиусе 3 блоков от своего расположения.", + "oc:tooltip.waypoint": "Добавляет путевую точку для устройств с навигационным улучшением.", + "oc:tooltip.wirelessnetworkcard": "Позволяет передавать сетевые сообщения по беспроводному каналу в дополнение к проводному. Вы можете настроить §fсилу сигнала§7, чтобы контролировать, насколько далеко должны отправляться сообщения. Более высокая сила сигнала приводит к повышенному потреблению энергии.", + "oc:tooltip.worldsensorcard": "Позволяет получать информацию об атмосфере и гравитации на планетах, добавляемых модом GalactiCraft. Используйте на свой страх и риск. Производитель не несет ответственности за материальный ущерб и увечья. У нас есть адвокаты. И деньги. Даже не пытайтесь.", + "oc:tooltip.wrench": "Гибрид отвертки и ключа.", + "achievement.oc.adapter": "Мы едины", + "achievement.oc.adapter.desc": "Дайте поработать с другими модами!", + "achievement.oc.assembler": "Великолепно", + "achievement.oc.assembler.desc": "Время захватывать мир!", + "achievement.oc.cable": "Не трогай провода!", + "achievement.oc.cable.desc": "... они от этого ржавеют", + "achievement.oc.capacitor": "Батарея в комплекте", + "achievement.oc.capacitor.desc": "Вы не можете остановить это.", + "achievement.oc.card": "Мы принимаем карточки", + "achievement.oc.card.desc": "Для вашего удобства. Вам это понравится.", + "achievement.oc.case": "В случае возникновения неполадок", + "achievement.oc.case.desc": "Открывайте боковую крышку летом.", + "achievement.oc.charger": "Ладно, сделаем это", + "achievement.oc.charger.desc": "Пошла зарядка.. черт, опять забыл редстоун сигнал.", + "achievement.oc.chip": "Полезные мелочи", + "achievement.oc.chip.desc": "Ведь электронные лампы - прошлый век", + "achievement.oc.cpu": "Разогнанный", + "achievement.oc.cpu.desc": "Время нагрузить его по полной.", + "achievement.oc.disassembler": "Больше не нужно", + "achievement.oc.disassembler.desc": "Когда великолепные идеи оказываются не такими уж и великолепными", + "achievement.oc.diskDrive": "Карусель", + "achievement.oc.diskDrive.desc": "Небольшая емкость, зато какой звук!", + "achievement.oc.drone": "Вездесущее око", + "achievement.oc.drone.desc": "Небольшой брат следит за тобой.", + "achievement.oc.eeprom": "Он может быть только один", + "achievement.oc.eeprom.desc": "Для каждого компьютера, то есть. Для загрузки компьютера, вы знали?", + "achievement.oc.floppy": "Не подносить магнит", + "achievement.oc.floppy.desc": "Дискеты не любят магниты.", + "achievement.oc.geolyzer": "Назад на землю", + "achievement.oc.geolyzer.desc": "Он имеет необычные свойства.", + "achievement.oc.graphicsCard": "Последнее поколение", + "achievement.oc.graphicsCard.desc": "Покажи это.", + "achievement.oc.hdd": "Продавец хотдогов", + "achievement.oc.hdd.desc": "Нет, подождите, это не то, о чем вы подумали. Не роняйте его...", + "achievement.oc.hologram": "Гиперпространство", + "achievement.oc.hologram.desc": "Когда двух измерений уже не хватает", + "achievement.oc.keyboard": "Крошкохранитель-3000", + "achievement.oc.keyboard.desc": "Не рекомендуется переворачивать и трясти его", + "achievement.oc.microcontroller": "Маленькая сестренка", + "achievement.oc.microcontroller.desc": "Просто маленький компьютер", + "achievement.oc.motionSensor": "Оно двигается", + "achievement.oc.motionSensor.desc": "Как Майкл Джексон.", + "achievement.oc.networkCard": "Нам надо поговорить!", + "achievement.oc.networkCard.desc": "Оставайтесь на связи с дальними родственниками.", + "achievement.oc.openOS": "Поехали", + "achievement.oc.openOS.desc": "Неужели он включится.", + "achievement.oc.powerDistributor": "Поделись с ближним", + "achievement.oc.powerDistributor.desc": "Когда вы помогаете распределять энергию.", + "achievement.oc.rack": "Прямо в стойку", + "achievement.oc.rack.desc": "Не знаю, о чем думаете вы, я думал о серверной стойке.", + "achievement.oc.raid": "Чрезмерная избыточность", + "achievement.oc.raid.desc": "Только диски не вынимайте.", + "achievement.oc.ram": "Случайный доступ к памяти", + "achievement.oc.ram.desc": "Поздравляем, вы делаете это правильно.", + "achievement.oc.redstoneCard": "Есть контакт", + "achievement.oc.redstoneCard.desc": "Возврат к аналоговой технике.", + "achievement.oc.redstoneIO": "Выскочка", + "achievement.oc.redstoneIO.desc": "Когда все сигналы в нужных местах", + "achievement.oc.robot": "Бип-пип", + "achievement.oc.robot.desc": "УНИЧТОЖИТЬ!", + "achievement.oc.screen": "Вы пробовали выключить и снова включить?", + "achievement.oc.screen.desc": "Серьезно. Редстоун сигнал может выключать монитор.", + "achievement.oc.server": "Выделенный сервер", + "achievement.oc.server.desc": "Облачные вычисления, мы идем к вам.", + "achievement.oc.switch": "Сложная топология", + "achievement.oc.switch.desc": "Избегайте сложных связей и потери пакетов.", + "achievement.oc.tablet": "Несъедобно", + "achievement.oc.tablet.desc": "Держите подальше от маленьких детей, во избежание пропажи денег на вашей кредитной карте.", + "achievement.oc.transistor": "Редстоун, скажи \"Привет.\"", + "achievement.oc.transistor.desc": "Создайте транзистор. Потом послушайте музыку. Не благодарите меня.", + "achievement.oc.wirelessNetworkCard": "Сигналы", + "achievement.oc.wirelessNetworkCard.desc": "Время идти туда, где никогда не появлялся сигнал.", + "death.attack.oc.nanomachinesOverload.1": "%s был слишком жадным.", + "death.attack.oc.nanomachinesOverload.2": "%s получил нервный срыв.", + "death.attack.oc.nanomachinesOverload.3": "Нанороботы %s вышли из под контроля.", + "death.attack.oc.nanomachinesHungry.1": "%s был съеден нанороботами.", + "death.attack.oc.nanomachinesHungry.2": "%s не кормил нанороботов.", + "death.attack.oc.nanomachinesHungry.3": "%s был переварен нанороботами.", + "nei.options.inventory.oredict": "Показывать имена Ore Dictionary", + "nei.options.inventory.oredict.true": "Да", + "nei.options.inventory.oredict.false": "Нет", + "nei.usage.oc.Manual": "Открыть руководство", + "option.oc.address": "Адрес", + "option.oc.componentName": "Название компонента", + "option.oc.energy": "Энергия" +} diff --git a/src/main/resources/assets/opencomputers/lang/tr_TR.lang b/src/main/resources/assets/opencomputers/lang/tr_TR.lang deleted file mode 100644 index c5f2217a52..0000000000 --- a/src/main/resources/assets/opencomputers/lang/tr_TR.lang +++ /dev/null @@ -1,496 +0,0 @@ -# Based off /src/main/resources/assets/opencomputers/lang/en_US.lang -# Initial localization by H. Utku Maden (Other authors should append their names in the list.) -# ------ -# Some translational loses may have been introduced. (Language translations may not be 100% correct) -# Please comment awkward translational situations. - -# Blocks -#===== - -tile.oc.adapter.name=Dönüştürücü -tile.oc.assembler.name=Elektronik Birleştirici -tile.oc.cable.name=Kablo - -# This translation is prefered. Do not change to 'kapasitör' or 'kondansatör'. -tile.oc.capacitor.name=Sığaç -# Sounds wierd, but was made with 'halı' to keep consistancy with minecraft's own localization. -tile.oc.carpetedcapacitor.name=Halılı Sığaç - -# Direct translation of tier does not exist, nearest is 'sınıf', but higher numbers are a worse object; so 'seviye' (level) was used -tile.oc.case1.name=Bilgisayar Kasası (1. Seviye) -tile.oc.case2.name=Bilgisayar Kasası (2. Seviye) -tile.oc.case3.name=Bilgisayar Kasası (3. Seviye) -tile.oc.casecreative.name=Bilgisayar Kasası (Yaratıcı) - -# Fictional things get fictional names -tile.oc.chameliumblock.name=Şamelyum Küpü -tile.oc.charger.name=Şarj Cihazı -tile.oc.disassembler.name=Ayrıştırıcı -tile.oc.diskdrive.name=Disket Sürücüsü -tile.oc.endstone.name=End Taşı -tile.oc.geolyzer.name=Jeolizer -tile.oc.hologram1.name=Hologram Projektörü (1. Seviye) -tile.oc.hologram2.name=Hologram Projektörü (2. Seviye) -tile.oc.keyboard.name=Klavye -tile.oc.microcontroller.name=Mikroişlemci -tile.oc.motionsensor.name=Hareket Algılayıcı -tile.oc.netsplitter.name=Ağ Bölücü -tile.oc.powerconverter.name=Güç Dönüştürücü -tile.oc.powerdistributor.name=Güç Dağıtıcı -tile.oc.print.name=3B Çıktı -tile.oc.printer.name=3B Yazıcı -tile.oc.raid.name=RAID -tile.oc.redstone.name=Kızıltaş G/Ç Küpü -tile.oc.relay.name=Ağ Tamponu -tile.oc.robot.name=Robot -tile.oc.robotafterimage.name=Robot -tile.oc.screen1.name=Ekran (1. Seviye) -tile.oc.screen2.name=Ekran (2. Seviye) -tile.oc.screen3.name=Ekran (3. Seviye) -tile.oc.rack.name=Sunucu Rafı -tile.oc.transposer.name=İletici -tile.oc.waypoint.name=Yer İşareti - -# Items -item.oc.abstractbuscard.name=Soyut Veriyolu Kartı -item.oc.acid.name=İspirto? -item.oc.alu.name=Aritmetik Mantık Birimi (ALU) -item.oc.analyzer.name=Analiz Aleti -item.oc.apu0.name=Eklentili İşlemci (APU) (1. Seviye) -item.oc.apu1.name=Eklentili İşlemci (APU) (2. Seviye) -item.oc.apu2.name=Eklentili İşlemci (APU) (Yaratıcı) -item.oc.arrowkeys.name=Ok Tuşları -item.oc.buttongroup.name=Harf Takımı -item.oc.cardbase.name=Ham Bilgisayar Kartı -item.oc.chamelium.name=Şamelyum -item.oc.circuitboard.name=Devre Kartı -item.oc.componentbus0.name=Cihaz Veriyolu (1. Seviye) -item.oc.componentbus1.name=Cihaz Veriyolu (2. Seviye) -item.oc.componentbus2.name=Cihaz Veriyolu (3. Seviye) -item.oc.componentbus3.name=Cihaz Veriyolu (Yaratıcı) -item.oc.controlunit.name=Yönetim Birimi (CU) -item.oc.cpu0.name=İşlemci (CPU) (1. Seviye) -item.oc.cpu1.name=İşlemci (CPU) (2. Seviye) -item.oc.cpu2.name=İşlemci (CPU) (3. Seviye) -item.oc.cuttingwire.name=Kesme Teli -item.oc.datacard0.name=Veri Kartı (1. Seviye) -item.oc.datacard1.name=Veri Kartı (2. Seviye) -item.oc.datacard2.name=Veri Kartı (3. Seviye) -item.oc.debugcard.name=Hata Ayıklama Kartı -item.oc.debugger.name=Ağ Hata Ayıklama Aleti -item.oc.diamondchip.name=Elmas Kesiti -item.oc.disk.name=Disk Bileşeni -item.oc.diskdrivemountable.name=Disk -item.oc.drone.name=Drone -item.oc.dronecase0.name=Drone Kasası (1. Seviye) -item.oc.dronecase1.name=Drone Kasası (2. Seviye) -item.oc.dronecase3.name=Drone Kasası (3. Seviye) -item.oc.eeprom.name=EEPROM -item.oc.floppydisk.name=Disket -item.oc.graphicscard0.name=Ekran Kartı (1. Seviye) -item.oc.graphicscard1.name=Ekran Kartı (2. Seviye) -item.oc.graphicscard2.name=Ekran Kartı (3. Seviye) -item.oc.harddiskdrive0.name=Hard Disk (1. Seviye) -item.oc.harddiskdrive1.name=Hard Disk (2. Seviye) -item.oc.harddiskdrive2.name=Hard Disk (3. Seviye) -item.oc.hoverboots.name=Uçma Botu -item.oc.inkcartridge.name=Mürekkep Kartuşu -item.oc.inkcartridgeempty.name=Mürekkep Kartuşu (Boş) -item.oc.internetcard.name=İnternet Kartı -item.oc.interweb.name=Ağ? -item.oc.ironnugget.name=Demir Parçası -item.oc.linkedcard.name=Bağlantılı Kart -item.oc.manual.name=OpenComputers Kullanma Kılavuzu -item.oc.memory0.name=Bellek (1. Seviye) -item.oc.memory1.name=Bellek (1,5. Seviye) -item.oc.memory2.name=Bellek (2. Seviye) -item.oc.memory3.name=Bellek (2,5. Seviye) -item.oc.memory4.name=Bellek (3. Seviye) -item.oc.memory5.name=Bellek (3,5. Seviye) -item.oc.microchip0.name=Entegre Devre (1. Seviye) -item.oc.microchip1.name=Entegre Devre (2. Seviye) -item.oc.microchip2.name=Entegre Devre (3. Seviye) -item.oc.microcontrollercase0.name=Mikroişlemci Kasası (1. Seviye) -item.oc.microcontrollercase1.name=Mikroişlemci Kasası (2. Seviye) -item.oc.microcontrollercase3.name=Mikroişlemci Kasası (Yaratıcı) -item.oc.nanomachines.name=Nanomakine -item.oc.networkcard.name=Ağ Kartı -item.oc.numpad.name=Tuş Takımı -item.oc.present.name=Çam Sakızı... -item.oc.printedcircuitboard.name=Devre Kartı (PCB) -item.oc.rawcircuitboard.name=Ham Devre Kartı -item.oc.redstonecard0.name=Kızıltaş Kartı (1. Seviye) -item.oc.redstonecard1.name=Kızıltaş Kartı (2. Seviye) -item.oc.server0.name=Sunucu (1. Seviye) -item.oc.server1.name=Sunucu (2. Seviye) -item.oc.server2.name=Sunucu (3. Seviye) -item.oc.server3.name=Sunucu (Yaratıcı) -item.oc.tablet.name=Tablet -item.oc.tabletcase0.name=Tablet Kasası (1. Seviye) -item.oc.tabletcase1.name=Tablet Kasası 500640(2. Seviye) -item.oc.tabletcase3.name=Tablet Kasası (Yaratıcı) -item.oc.terminal.name=Uzaktan Uçbirim -item.oc.terminalserver.name=Uçbirim Sunucusu -item.oc.texturepicker.name=Doku Seçici -item.oc.transistor.name=Transistör -item.oc.upgradeangel.name=Melek Eklentisi -item.oc.upgradebattery0.name=Batarya Eklentisi (1. Seviye) -item.oc.upgradebattery1.name=Batarya Eklentisi (2. Seviye) -item.oc.upgradebattery2.name=Batarya Eklentisi (3. Seviye) -item.oc.upgradechunkloader.name=Kesiti-yüklü-tut Eklentisi -item.oc.upgradecontainercard0.name=Kart Yuvası (1. Seviye) -item.oc.upgradecontainercard1.name=Kart Yuvası (2. Seviye) -item.oc.upgradecontainercard2.name=Kart Yuvası (3. Seviye) -item.oc.upgradecontainerupgrade0.name=Eklenti Yuvası (1. Seviye) -item.oc.upgradecontainerupgrade1.name=Eklenti Yuvası (2. Seviye) -item.oc.upgradecontainerupgrade2.name=Eklenti Yuvası (3. Seviye) -item.oc.upgradecrafting.name=Üretim Eklentisi -item.oc.upgradedatabase0.name=Veritabanı Eklentisi (1. Seviye) -item.oc.upgradedatabase1.name=Veritabanı Eklentisi (2. Seviye) -item.oc.upgradedatabase2.name=Veritabanı Eklentisi (3. Seviye) -item.oc.upgradeexperience.name=Deneyim Eklentisi -item.oc.upgradegenerator.name=Jeneratör Eklentisi -item.oc.upgradehover0.name=Uçma Eklentisi (1. Seviye) -item.oc.upgradehover1.name=Uçma Eklentisi (2. Seviye) -item.oc.upgradeinventory.name=Envanter Eklentisi -item.oc.upgradeinventorycontroller.name=Envanter Yönetimi Eklentisi -item.oc.upgradeleash.name=Kayış Eklentisi -item.oc.upgrademf.name=MFU -item.oc.upgradenavigation.name=Yönbulma Eklentisi -item.oc.upgradepiston.name=Piston Eklentisi -item.oc.upgradesign.name=Tabela G/Ç Eklentisi -item.oc.upgradesolargenerator.name=Güneş Enerjisi Eklentisi -item.oc.upgradetank.name=Tank Eklentisi -item.oc.upgradetankcontroller.name=Tank Yönetimi Eklentisi -item.oc.upgradetractorbeam.name=Çekme Işını Eklentisi -item.oc.upgradetrading.name=Ticaret Eklentisi -item.oc.wirelessnetworkcard0.name=Kablosuz Ağ Kartı (1. Seviye) -item.oc.wirelessnetworkcard1.name=Kablosuz Ağ Kartı (2. Seviye) -item.oc.worldsensorcard.name=Dünya Algılayıcı Kartı -item.oc.wrench.name=Tornanahtar - -# Entities -entity.oc.Drone.name=Drone - -# GUI -oc:gui.Analyzer.Address=§6Adres§f: %s -oc:gui.Analyzer.AddressCopied=Adres panoya kopyalandı -oc:gui.Analyzer.ChargerSpeed=§6Şarj hızı§f: %s -oc:gui.Analyzer.ComponentName=§6Parça adı§f: %s -oc:gui.Analyzer.Components=§6Bağlı parça sayısı§f: %s -oc:gui.Analyzer.CopyToClipboard=Panoya kopyalamak için tıklayın. -oc:gui.Analyzer.LastError=§6Son hata§f: %s -oc:gui.Analyzer.RobotName=§6Adı§f: %s -oc:gui.Analyzer.RobotOwner=§6Sahibi§f: %s -oc:gui.Analyzer.RobotXp=§6Deneyimi§f: %s (Seviye %s) -oc:gui.Analyzer.StoredEnergy=§6Depoladığı enerji§f: %s -oc:gui.Analyzer.TotalEnergy=§6Maksimum enerji miktarı§f: %s -oc:gui.Analyzer.Users=§6Kullanıcılar§f: %s -oc:gui.Analyzer.WirelessStrength=§6Sinyal gücü§f: %s -oc:gui.Assembler.Collect=Çıktıyı al -oc:gui.Assembler.Complexity=Karmaşıklık: %s/%s -oc:gui.Assembler.InsertCase=Kasa koyun -oc:gui.Assembler.InsertCPU=İşlemci koyun -oc:gui.Assembler.InsertRAM=Bellek koyun -oc:gui.Assembler.Progress=İlerleme: %s%% (%s) -oc:gui.Assembler.Run=Birleştir -oc:gui.Assembler.Warning.BIOS=BIOS -oc:gui.Assembler.Warning.GraphicsCard=Ekran Kartı -oc:gui.Assembler.Warning.Inventory=Envanter Eklentisi -oc:gui.Assembler.Warning.Keyboard=Klavye -oc:gui.Assembler.Warning.OS=Başlangıç Bölümü -oc:gui.Assembler.Warning.Screen=Ekran -oc:gui.Assembler.Warnings=§eUyarı§7: Önerilen parçalar eksik. -oc:gui.Chat.NewVersion=Yeni bir sürüm çıktı: %s -oc:gui.Chat.TextureName=§7Doku adı §a%s§f. -oc:gui.Chat.WarningClassTransformer=Sınıf dönüştürücü çalışırken §chatalar§f oluştu. Lütfen bunu mod yazarlarına (bütün!) FML §alatest.log§f/§afml-server-latest.log§f kayıt dosyasıyla birlikte gönderiniz. Şimdiden teşekkür ederiz. -#There were §cerrors§f running the class transformer. Please report this, together with your (full!) FML §alatest.log§f/§afml-server-latest.log§f logfile, thank you! -oc:gui.Chat.WarningFingerprint=§cUYARI§f - Parmakizi uyuşmazlığı! '§a%s§f' beklerken '§e%s§f' bulduk. Eğer karılmamış sürümünü kullanan bir mode yazarı değilseniz OpenComputers modunu yeniden indirmeniz §lşiddetle§f tavsiye edilir; çünkü elinizdeki JAR dosyası ile oynanmış olabilir. -# §cWARNING§f - fingerprint mismatch! Expected '§a%s§f' but got '§e%s§f'. Unless you are a modder and are running the deobfuscated version of the mod, it is §lstrongly§f recommended to redownload OpenComputers, because the JAR you are using may have been tampered with. -oc:gui.Chat.WarningLink=Bağlantı açılamadı: %s -oc:gui.Chat.WarningLuaFallback=Orijinal Lua kütüphaneleri bulunamadı ve bilgisayarlar durumlarını koruyamayacak. Bölümler yeniden yüklenince bilgisayarlar yeniden başlayacak. (Yedek kütüphaneler kullanılıyor) -# Native Lua libraries are not available, computers will not be able to persist their state. They will reboot on chunk reloads. -oc:gui.Chat.WarningProjectRed=OpenComputers'ı desteklemeyen bir Project: Red sürümünü kullanıyorsunuz. Project: Red'i güncellemeyi deneyin. -# You are using a version of Project: Red that is incompatible with OpenComputers. Try updating your version of Project: Red. -oc:gui.Chat.WarningRecipes=Bir veya birden fazla tarifi yüklerken hata oluştu. Bazı nesneler üretilemeyebilir. Daha fazla bilgi için kayıt defteri dosyanızı bakın. -# There were errors loading one or more recipes. Some items may be uncraftable. Please check your log file for more information. -oc:gui.Chat.WarningSimpleComponent= §aSimpleComponent§f arayüzünü kullanan bir mod eklentisi (acep sizin mi?) §eyanlış bir şeyler§f yaptı. Parça mantığı enjekte edilemedi. Daha fazla bilgi için kayıt defteri dosyanıza bakın. -# An addon (yours?) using the §aSimpleComponent§f interface did §esomething wrong§f. Component logic could not be injected. Please check your log file for more information. -oc:gui.Drive.Managed=Denetimli -oc:gui.Drive.Unmanaged=Denetimsiz -oc:gui.Drive.Warning=§lUyarı§r: kip değiştirmek disk üzerindeki bütün verinin kaybına sebep olur. -oc:gui.Error.ComponentOverflow=Bilgisayara çok parça takılı. -oc:gui.Error.InternalError=İçsel bir hata, lütfen kayıt defterine bakın. Bu büyük ihtimalle bir yazılım sorunu. -oc:gui.Error.NoCPU=Bilgisayarın işlemcisi yok. -oc:gui.Error.NoEnergy=Güç yeterli değil. -oc:gui.Error.NoRAM=Bilgisayarda bellek yok. -oc:gui.Error.OutOfMemory=Bellek taştı. -oc:gui.Manual.Blocks=OpenComputers Küpler -oc:gui.Manual.Home=Ev -oc:gui.Manual.Items=OpenComputers Nesneler -oc:gui.Manual.Warning.BlockMissing=Küp yok. -oc:gui.Manual.Warning.ImageMissing=Resim bulunamadı. -oc:gui.Manual.Warning.ItemMissing=Nesne yok. -oc:gui.Manual.Warning.OreDictMissing=Cevher Muadilleri Sözlüğü yok. -oc:gui.Raid.Warning=§4Disk eklemek onu siler.[nl] Disk çıkarmak RAID'i siler. -oc:gui.Robot.Power=Güç -oc:gui.Robot.TurnOff=Kapat -oc:gui.Robot.TurnOn=Aç[nl]§7Hata çözmek için analiz aletini kullanın.§r -oc:gui.Rack.Back=Arka -oc:gui.Rack.Bottom=Alt -oc:gui.Rack.Left=Sol -oc:gui.Rack.None=Hiç -oc:gui.Rack.Right=Sağ -oc:gui.Rack.Enabled=Aktif -oc:gui.Rack.Disabled=İnaktif -oc:gui.Rack.Top=Üst -oc:gui.Switch.PacketsPerCycle=Paket / devir -oc:gui.Switch.QueueSize=Sıra Uzunluğu -oc:gui.Switch.TransferRate=Devir hızı -oc:gui.Terminal.InvalidKey=Geçersiz anahtar. Büyük ihtimalle başka bir uçbirim sunuzuya bağlandı. -oc:gui.Terminal.OutOfRange=Sinyal yok. - -# Containers -oc:container.adapter=Dönüştürücü -oc:container.case=Bilgisayar -oc:container.charger=Şarj Aleti -oc:container.disassembler=Ayrıştırıcı -oc:container.diskdrive=Disket Sürücüsü -oc:container.printer=Yazıcı -oc:container.raid=RAID -oc:container.relay=Ağ Tamponu -oc:container.server=Sunucu -oc:container.rack=Sunucu Rafı -oc:container.tabletwrapper=Tablet - -# Keybinds -key.clipboardPaste=Panodan Yapıştır - -# Item / Block Tooltips -oc:tooltip.abstractbuscard=LIP paketleri alıp ileterek §fStargateTech 2§7'in soyut veriyolu ile iletişim kurmanızı sağlar. -oc:tooltip.acid=Zehirli, alkol kokan sıvımtırak bir şey. Belki askerde bazı manyak herifler kafayı bulmak için içer. Başka kullanım alanları da olabilir. -oc:tooltip.adapter=Parça olmayan blokları (örneğin "vanilla" bloklar veya diğer modların bloklarını) kumanda etmek için kullanılır. -oc:tooltip.alu=Siz yorulmayın diye sizin için işlem yapar. Belki böylesi daha iyidir. -oc:tooltip.analyzer=Blokların §fadresi§7 ve §fparça ismi§7 gibi özelliklerini gösterir.[nl] Ayrıca bilgisayarın beklenmedik bir şekilde kapanmasına sebep olan hatayı da gösterir. -# Used to display information about blocks, such as their §faddress§7 and §fcomponent name§7.[nl] Also displays the error that caused a computer to crash if it did not shut down normally. -oc:tooltip.apu= Ekran kartı olan bir işlemci, bir kart yuvasına daha ihtiyacınız olursa diye.[nl] Desteklenen parçalar: §f%s§7[nl] Maksimum çözünürlük: §f%sx%s§7[nl] Maksimum renk derinliği: §f%s§7[nl] İşlem/tick: §f%s§7 -# This is a CPU with an integrated GPU (or IGP), when you just need that extra card slot.[nl] Supported components: §f%s§7[nl] Maximum resolution: §f%sx%s§7[nl] Maximum color depth: §f%s§7[nl] Operations/tick: §f%s§7 -oc:tooltip.assembler=Bilgisayar parçalarından robot ve başka cihazları üretmenize yarar. -oc:tooltip.cable=Blokları bağlamanın ucuz bir yolu. -oc:tooltip.capacitor=Daha sonra kullanılmak üzere enerji depolar. Çok hızlı şarj ve desarj olabilir. -oc:tooltip.carpetedcapacitor=Daha sonra kullanılmak üzere enerji depolar. Çok hızlı şarj ve desarj olabilir. Bir Oselo veya Koyun üstünde yürürse şarj olur. -oc:tooltip.cardbase=Adı üstünde, tüm bilgisayar kartlarının en basit yapıtaşı. -oc:tooltip.case=Bilgisayar kasası bilgisayarın yapıtaşıdır ve bilgisayarın §fkartlarını§7, §fbelleğini§7 ve §fsürücülerimi§7 bünyesimde barındırır.[nl] Yuvalar: §f%s§7 -# The Computer Case is the basic building block for computers and houses the computer's §fextension cards§7, §fRAM§7 and §fhard disks§7.[nl] Slots: §f%s§7 -oc:tooltip.chamelium=3B çıktılar için hammaddedir. Yutmayınız, körlük ve geçici bilinç kaybına sebep olabilir. -oc:tooltip.chameliumblock=Hoş ve temiz. 3B çıktılarda renkli şekiller yaratmak veya üssünüzü temiz ve renkli bir blokla dekore etmek için kullanılabilir. -oc:tooltip.charger=Sığaçlardan takındaki robotlara ve dronlara enerji aktarır. Aktarım hızı gelen §fkızıltaş sinyaline§7 bağlıdır; tam güç tam hızla şarj olması, hiç sinyal olmaması ise şarj olmaması demektir. Tabletleri de şarj etmek, hatta sürücülerine erişmek için kullanılabilir. -oc:tooltip.circuitboard=İşte şimdi yol alıyoruz. İşleme tabi tutularak devre kartı elde edilebilir. -oc:tooltip.controlunit=Bu birim... yönetiyor işte. İşlemciye ihtiyacın var o yüzden önemli, değil mi? -oc:tooltip.componentbus=Bu eklenti sunucuların aynı anda daha çok parça ile bağlantı kurmasını sağlar, işlemciler gibi.[nl] Desteklenen parçalar §f%s§7 -oc:tooltip.cpu=Her bilgisayara lazım. Saati biraz istikrarsız ama cep saatinden o kadar oluyor. Çok sarsma.[nl]Desteklenen parçalar: §f%s§7 -oc:tooltip.cpu.Architecture=Mimari: §f%s§7 -oc:tooltip.cuttingwire=Kil blokları devre kartı şekline sokmak için kullanılır. Tek kullanımda kopar. Ne iğrenç bir alet bu. -oc:tooltip.datacard0="hashing", "deflate"/"inflate" gibi birkaç gelişmiş algoritma sunar. -oc:tooltip.datacard1="hashing", "deflate"/"inflate", AES şifreleme gibi birkaç gelişmiş algoritma sunar. -oc:tooltip.datacard2="hashing", "deflate"/"inflate", AES şifreleme, eliptik eğri kriptografisi gibi birkaç gelişmiş algoritma sunar. -oc:tooltip.debugcard=Test etmeyi kolaylaştıran, dünyayı manüpile eden Yaratıcı mod aracı. Yetişkin denetimi altında kullanın. -oc:tooltip.debugger=OpenComputers'ın iç ağının hata ayıklama bilgisini toplamak için kullanılır. Sadece bir geliştirici isterse kullanınız. -oc:tooltip.diamondchip=Parıltılı bir elmasın naçiz bir parçası. Asla eskisi gibi olamayacak. -oc:tooltip.disassembler=Nesneleri ihtiva ettiği parçalarına ayrıştırır. §lUyarı§7: ayrışan parçaların ayrışma sürecinde %%%s bozulma olasılığı vardır. -oc:tooltip.disk=Daimi veri depolama cihazları yapılabilen ilkel veri saklama dairesi. -oc:tooltip.diskdrive.CC=ComputerCraft disketler §açalışır§7. -oc:tooltip.diskdrive=Disket okuma ve yazmaya yarar. Daha sonra disket takmak için robotlara da takılabilir. -oc:tooltip.diskdrivemountable=Normal bir sürücüyle aynı işlevi görür fakat bir sunucu rafına takılmalıdır. -oc:tooltip.diskusage=Disk kullanımı: %s/%s Byte -oc:tooltip.diskmodemanaged=Kip: Denetimli -oc:tooltip.diskmodeunmanaged=Kip: Denetimsiz -oc:tooltip.drone=Dronlar hafif, hızlı, az yük kapasiteli uçan cihazlardır. -oc:tooltip.dronecase=Bu kasa birleştirici ile Drone yapmak için kullanılır. Sınırlı parça için alanı var ve end taşı ile güçlendirilmiş uçma kabiliyeti var. -oc:tooltip.eeprom=Elektrikle silinebilir, programlanabilir salt okunur hafıza. Bilgisayarların çalışması için gerekli BIOS kodunu içerir. -oc:tooltip.fakeendstone=Neredeyse aynısı, bu da havalanmaya meyilli. -oc:tooltip.geolyzer=Yakındaki blokların sertliğini ölçmeye yarar. Bu bilgi cevher bulmak için bölgenin holgramını yapmaya yarayabilir. -oc:tooltip.graphicscard=Ekranları güzel bilgilerle doldurur.[nl] Azami Çözünürlük: §f%sx%s§7[nl] Azami renk derinliği: §f%s§7[nl] İşlem/tick: §f%s§7 -oc:tooltip.hoverboots=Daha yükseğe sıçra, daha derine in, daha iyi yürü. Hepsi Uçan Bot (TM) sayesinde. -oc:tooltip.inkcartridge=3B yazıcılara mürekkep koymak için kullanılır. Nedense makineye takılı kalmıyor. -oc:tooltip.inkcartridgeempty=Yazıcının kartuşu yine birmiş. Mürekkebi doldurabilirsin. Ya da at gitsin. Nasıl olsa bir daha aynı yazmaz. -oc:tooltip.internetcard=Bu kart ile gerçekten internete bağlanıp, TCP üzerinden HTTP istemlerinde bulunabilirsiniz. -oc:tooltip.interweb=Tebrikler, bir ağ (?) kazandınız. Internete bununla bağlanabilirsiniz. Trollerin seviyesine inmmeyin. -oc:tooltip.ironnugget=Demirden kopan bir parça, başka nasıl açıklayayım. -oc:tooltip.keyboard=Yazı yazmak için ekranlara takılabilir. -oc:tooltip.hologram0=Bilgisayarla kumanda edilen, voksel tabanlı yapıları göstermek için kullanılan hacimsel ekran.[nl] Çözünürlük: §f48x32x48§7 [nl] Azami Ölçek: §f3x§7 [nl] Renk derinliği: §fMonokrom§7 -oc:tooltip.hologram1=Bilgisayarla kumanda edilen, voksel tabanlı yapıları göstermek için kullanılan hacimsel ekran.[nl] Çözünürlük: §f48x32x48§7 [nl] Azami Ölçek: §f3x§7 [nl] Renk derinliği: §f3 Renkli§7 -oc:tooltip.linkedcard=Bunlar çiftler halinde üretilir ve sadece partneriyle iletişim kurarlar. İletişimleri mesafeyi ve boyutları engel tanımaz fakat çok güç ister. -oc:tooltip.linkedcard_channel=§8Kanal: %s§7 -oc:tooltip.manual=OpenComputers hakkında ihtiyaç duyabileceğiniz her bilgi ve daha fazlası. Hem de sadece ... §ofiyatı öğrenmek için R'ye basın§7. -oc:tooltip.memory=Bilgisayarların çalışması için gerekli. Ne kadar çok belleğiniz varsa o kadar karmaşık programlar çalıştırabilirsiniz. -oc:tooltip.microchip=Siyah elektrikle çalışan zımbırtılar. Neden kızıltaşla çalıştıkları beni aşıyor. -oc:tooltip.microcontroller=Mikroişlemciler bilgisayarların en asgari biçimi. Görev odaklıdırlar ve EEPROM'larında gelen tek bir programla çalışırlar.[nl] §cHarici parçalarla bağlantı kuramazlar.§7 -oc:tooltip.microcontrollercase=Mikroişlemcilerin temel bileşeni. Mikroişlemci yapmak için bir birleştirici kullanın ve başka parçalar ekleyin. -oc:tooltip.motionsensor=Yakındaki canlıların hareketini algılar. Çalışması için canlılar görüş açısında olmalıdır. -oc:tooltip.nanomachines=Kumanda birimi ve tüketilmek üzere bir sürü nanomakine, tabi sende o mide varse. -oc:tooltip.networkcard=Uzaktaki, birbirine başka bloklarla bağlı (örneğin kablolarla) bilgisayarların birbirlerine mesajlar göndererek iletişim kurmasını sağlar. -oc:tooltip.poweracceptor=Enerji dönüşüm hızı: §f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§fBuildCraft MJ'si§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§fFactorization Yükü§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fIndustrialCraft² EU'su§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§fMekanism Joule'ü§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fThermal Expansion RF'i§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fResonant Engine Coulomb'u§7: §a%s:%s§7 -oc:tooltip.powerconverter=Başka modların enerjilerini OpenComputers'ın kendi enerji birimine dönüştürür. Dönüşüm oranları: -oc:tooltip.powerdistributor=Farklı ağlara enerji dağıtır. Ayrı kalması gereken alt-ağlara dönüştürücüden gelen enerjiyi dağıtmak için bire bir. -oc:tooltip.present=... çoban armağanı. Verdiğimiz rahatsızlıktan dolayı. Hediyeyi açarak §kganimetlere§7 sahip olabilirsiniz.[nl]§8Doğru zamanda OpenComputers parçaları üreterek hediye kazanabilirsiniz.§7 -oc:tooltip.print.BeaconBase=§8Fener tabanı olarak işlev görür. -oc:tooltip.print.LightValue=§8Işınan ışık: %s. -oc:tooltip.print.RedstoneLevel=§8Kızıltaş çıktısı: %s. -oc:tooltip.printedcircuitboard=Bellek, bilgisayar kartları vb.nin yapı taşı. -oc:tooltip.printer=Kullanıcı tanımlı nesnelerin şamelyum ve mürekkep kullanılarak basılmasını sağlar. Bir bilgisayar tarafından yönetilmelidir. Bazı sebeplerden dolayı, çocuklardan uzak tutun. -oc:tooltip.raid=Birden fazla diskin tek bir dosya sistemi altında birleştirilip bağlı tüm bilgisayarlar tarafından kullanılmasını sağlar. -oc:tooltip.rawcircuitboard=Herhangi bir fırında kurutulabilir. -oc:tooltip.redstone=Bloğun çevresinde kızıltaş iletimi ve çevresinden kızıltaş alıgalma yapabilir. Bağlı herhangi bir bilgisayar kumanda edebilir. Harici bir kızıltaş kartı gibi davranır. -oc:tooltip.redstonecard.ProjectRed=§fProject: Red§7 §adestekli§7. -oc:tooltip.redstonecard.RedLogic=§fRedLogic§7 §adestekli§7. -oc:tooltip.redstonecard.RedNet=§fRedNet§7 §adestekli§7. -oc:tooltip.redstonecard.WirelessCBE=§fWireless Redstone (ChickenBones)§7 §adestekli§7. -oc:tooltip.redstonecard.WirelessSV=§fWireless Redstone (SlimeVoid)§7 §adestekli§7. -oc:tooltip.redstonecard=Bilgisayarın veya robotun çevresine kızltaş sinyali iletimesini ve çevresinden kızıltaş sinyalı algılamasını sağlar. -oc:tooltip.relay=Farklı ağları birbirine bağlamaya yarar. Sadece ağ mesajları iletilir, parçalar görünmez. Bunu Ağ kartlarını kullanırken bilgisayarları birbirinden izole etmek için kullanabilirsiniz. -oc:tooltip.robot=Bilgisayarların aksine robotlar oyuncular gibi dünyada hareket edebilir ve ona değişiklikler yapabilir.[nl] §cHarici parçalara bağlanamaz.§7 -# the underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§fSeviye§7: §a%s§7 -oc:tooltip.robot_storedenergy=§fDepolu enerji§7: §a%s§7 -oc:tooltip.screen=Yazı göster, kasadaki bir ekran kartı aracılığıyla. [nl] Azami çözünürlük: §f%sx%s§7[nl] Azami renk derinliği: §f%s§7 -oc:tooltip.server=Bu bir sunucu. Bundan çokça olabilir fakat bu (bir bilgisayar gibi) başka parçalarla geliştirilebilir. Sunucu rafına takılarak çalıştırılabilir. -oc:tooltip.server.Components=Takılı Parçalar: -oc:tooltip.rack=4 sunucunun veya rafa konulabilen parçaların takılmasını sağlar. -oc:tooltip.tablet=Lua ile eğlence için bir tablet bilgisayar. Çömelirken aktifleştirirseniz kapanmaya sorlarsınız. -oc:tooltip.tabletcase=Basit bir tablet kasası. Bir birleştirici ve başka parçalar ile bir tablet yapabilirsiniz.. -oc:tooltip.terminal=Menzili içinde bir sunucuyu uzaktan kumanda etmenize yarar. Taşınabilir ekran ve klavye gibi davranır. Shift+Sağ-Tık ile raftaki bir sunucuya bağlayabilirsiniz. -oc:tooltip.terminalserver=Uzaktan Uçbirimin yöneticisi. Sanal bir ekranı ve klavyesi var. -oc:tooltip.texturepicker= Bu alet, 3B yazıcıda şekil tanımlamak üzere bir bloğun yüzeyini ifade eden bir metin gösterir. Kesinlikle dokunun ismi değil. Sana yalan borcum mu var? -oc:tooltip.tier=§8%s. Seviye -oc:tooltip.netsplitter=Ayarlanabilir bir bağlantı noktası gibi davranır. Her yüzün bağlantısı bir İngiliz anahtarı ile değiştirilebilir. Her yüzün bağlantısı bir kızıltaş sinyali ile tersine dönüştürülebilr. -oc:tooltip.toolong=Şuna basılı tutarak daha detaylı bilgi alabilirsiniz: [§f%s§7] -oc:tooltip.transistor=Çoğu bilgisayar parçasının basit bir bileşeni. Biraz yamulmuş ama iş görür. -oc:tooltip.transposer=Bitişiğindeki envanterler arasında katı ve sıvı değişimini sağlar. -oc:tooltip.upgradeangel=Robotlara boşlukta (tutunacak yer yokken) blok koyma yetisi sağlar. -oc:tooltip.upgradebattery=Cihazın depolayabileceği enerji miktarını arttırır. Böylece cihaz şarj olmadan daha uzun süre çalışabilir. [nl] Kapasite: §f%s§7 -oc:tooltip.upgradechunkloader=Robot tek başına ormana giderse ve onu kimse görmezse hareket eder mi? Bu eklenti çalıştığından emin olur. Bir bölümü(16x16x256) sürekli yüklü tutar fakat sürekli enerji harcar. -oc:tooltip.upgradecontainercard=Bu yuva birleştirilmiş cihazda kartların rahatlıkla takılıp çıkarılmasını sağlar. [nl] Azami Seviye: §f%s§7 -oc:tooltip.upgradecontainerupgrade=Bu yuva birleştirilmiş cihazda eklentilerin rahatlıkla takılıp çıkarılmasını sağlar. [nl] Azami Seviye: §f%s§7 -oc:tooltip.upgradecrafting=Robotun envanterinin sol üst köşesini çalışma masası gibi kullanmasını sağlar. Nesnelerin tarife göre yerleşmesi şarttır. -oc:tooltip.upgradedatabase=Bu eklenti deste bilgisinin başka parçalar tarafından kullanılmak üzere saklanmasını sağlar.[nl] Desteklenen satır sayısı: §f%s§7 -oc:tooltip.upgradeexperience=Bu eklenti çeşitli eylemler aracalığıyla robotların deneyim kazanmasını sağlar. Robotlar ne kadar deneyimliyse o kadar enerji depolayabilir, o kadar hızlı blok toplayabilir ve aletleri o kadar etkili kullanabilir. -oc:tooltip.upgradegenerator=Yolda yakıttan enerji üretimini sağlar. Yakıtları enerji değerlerine göre enerji üretmek için kullanır.[nl] §fVerimlilik§7: §a%s%%§7 -oc:tooltip.upgradehover=Bu eklenti robotun duvar tırmanmak zorunda kalmadan daha yükseğe çıkmasını sağlar.[nl] Azami irtifa: §f%s§7 -oc:tooltip.upgradeinventory=Bu eklenti bir robota veya drona envanter sağlar. Bu olmadan nesne tutamazlar. -oc:tooltip.upgradeinventorycontroller=Bu eklenti robotların ve dronların harici envanterlerle iletişim kurmasını ve onlardaki aletlerle kendi aletini değişmesini sağlar. -oc:tooltip.upgrademf=Dönüştürücülerin bitişiğinde olmadığı nesnelerle iletişim kurmasını sağlar. -oc:tooltip.upgrademf.Linked=§fBağlantı kuruldu§7 -oc:tooltip.upgrademf.Unlinked=§fBağlantı yok§7 -oc:tooltip.upgradeleash=Drone gibi bazı cihazların belediye görevlilerine sataş...-özür dilerim. Bu cihaz aslında canlı(lar)ı bağlamak için kullanılıyormuş. İlğinç. -oc:tooltip.upgradenavigation=Cihazın yönünü ve yerini tespit etmek için kullanılır. Yer bilgisi eklentiyi üretirken kullanılan haritanın merkez noktasına göredir. -oc:tooltip.upgradepiston=Bu eklenti çok itici. Piston gibi blokları hareket ettirmeye yarar. Canlıları ve partikülleri hareket ettir§lmez§7. -oc:tooltip.upgradesign=Tabelalardan yazı okumayı ve onlara yazı yazmayı sağlar. -oc:tooltip.upgradesolargenerator=Güneşten enerji üretimini sağlar. Gökyüzü görüş açısında olmalıdır. Bir Stirling motorunun %%%s katı hızı kadar hızlı enerji üretebilir. -oc:tooltip.upgradetank=Robotlara ve dronlara sıvı depolama alanı sağlar. Bu olmadan sıvı depolayamazlar. -oc:tooltip.upgradetankcontroller=Bu eklenti robotlara ve dronlara harici sıvı depoları ile iletişim yeteneği sağlar. Harici depodan dahiliye, dahiliden hariciye sıvı iletimi sağlar. -oc:tooltip.upgradetractorbeam=Nesne mıknatısı adı verilen çok gelişmiş bir teknolojiti edinin. Cihazın 3 block menzilinden nesneleri almasını sağlar. -oc:tooltip.waypoint=Yönbulma eklentisi olan cihazlar için referans noktası oluşturur. -oc:tooltip.wirelessnetworkcard=Normal ağ mesajlarının yanı sıra kablosuz ağ mesajlarının iletimini sağlar. §fSinyal gücünü§7 ayarlayarak mesajların ne kadar uzağa iletildiğini kontrol edebilirsiniz. Yüksek sinyal gücü daha çok enerji tüketir. -oc:tooltip.worldsensorcard=Dünya hakkında yerçekimi ve nefes alınabilir bir atmosferi olup olmadığı gibi bilgileri toplar. Bilgiler kesin değildir. Üretici firma karttan edilen bilgilere göre verilen kararlar sonucu oluşan maddi ve manevi hiçbir hasardan sorumlu değildir. Avukatlarımız var. Paramız da. Denemeyi aklınızdan bile geçirmeyin. -oc:tooltip.Wrench=İngiliz anahtarı tornavida karışımı bir şey. Öğrenmesi basit, ustalaşması zor. - -#Achievements -achievement.oc.adapter=Tak-Çalıştır -achievement.oc.adapter.desc=Diğer modların ve elbette vanilla Minecraft blokları ile iletişim kur. -achievement.oc.assembler=Harika -achievement.oc.assembler.desc=Dünyayı ele geçirme vakti. -achievement.oc.cable=Temiz Kablo -achievement.oc.cable.desc=Patentli dolanma önleyici teknolojisi ile. -achievement.oc.capacitor=Piller Ürüne Dahildir. -achievement.oc.capacitor.desc=Durduramazsın. -achievement.oc.card=Kredi Kartı Geçerlidir. -achievement.oc.card.desc=Sizin için. Kesinlikle bir art niyetimiz yok. -achievement.oc.case=Yangın Durumunda ... -achievement.oc.case.desc=Çünkü küp kasalar en iyisi. -achievement.oc.charger=Haydi şu işi bitirelim. -achievement.oc.charger.desc=Şarj etsene seni... Kızıltaş sinyalini unutmuşum. -achievement.oc.chip=En Küçüğünden Lütfen -achievement.oc.chip.desc=Çünkü tüpler eskide kaldı. -achievement.oc.cpu=Modifiye -achievement.oc.cpu.desc=Haydi bu makineyi biraz zorlayalım. -achievement.oc.disassembler=Ali Yazar, Veli Bozar -achievement.oc.disassembler.desc=Nasıl olsa Sarı Çizmeli Mehmet Ağa bir gün öder hesabı. -achievement.oc.diskDrive=Dönmedolap -achievement.oc.diskDrive.desc=Az alan, güzel ses. -achievement.oc.drone=Su gibi git... -achievement.oc.drone.desc=... su gibi gel. Pahalısın lazımsın bize. -achievement.oc.eeprom=Ya ben, ya hiç! -achievement.oc.eeprom.desc=Bilgisayar için, önemli bir parça. -achievement.oc.floppy=Güneş Tutulması -achievement.oc.floppy.desc=Hepsini bozduk 1999'da. -achievement.oc.geolyzer=Zonguldak -achievement.oc.geolyzer.desc=Toprak ne ki, yeri bir metre kaz kömür çıkıyor. -achievement.oc.graphicsCard=Yeni Nesil -achievement.oc.graphicsCard.desc=Döviz kuru düşseydi fakir kalmazdım. -achievement.oc.hdd=Hıyar Domates Dirhem -achievement.oc.hdd.desc=Yanlış oldu, bekle dilimin ucunda. -achievement.oc.hologram=Gelecek Boyut -achievement.oc.hologram.desc=2B'tan sıkıldın mı? -achievement.oc.keyboard=TozMıknatısı3000 -achievement.oc.keyboard.desc=Odanıza alın, odanız tertemiz olsun*. *TozMıknatısı300 dışında. -achievement.oc.microcontroller=Kardeş -achievement.oc.microcontroller.desc=Bilgisayarın küçük kardeşi. -achievement.oc.motionSensor=Tuvalet Kabusu -achievement.oc.motionSensor.desc=İşerken ışık söner mi acaba? -achievement.oc.networkCard=Feysbuk -achievement.oc.networkCard.desc=Hep birlikte kimsenin takmadığı şeyleri paylaşıp sosyal olduğumuzu sanıyoruz. -achievement.oc.openOS=iŞlEtİm SiStEmİ NeY? -achievement.oc.openOS.desc=Bilgisayarcıya git format atsın ablacım. -achievement.oc.powerDistributor=Hayat Paylaşınca Güzel -achievement.oc.powerDistributor.desc=Reklam yapmıyoruz. Güzel sözün telif hakkı mı olur? -achievement.oc.rack="Bizim salondaki raf olur mu?" -achievement.oc.rack.desc=Tartmaz bir kere. -achievement.oc.raid=Yerim Kalmadı. -achievement.oc.raid.desc=Ne kadar çok "aile fotoğrafı"n varsa artık. -achievement.oc.ram=Seçici Hatıra -achievement.oc.ram.desc=Nedense sevdiklerimi daha çok hatırlıyorum. -achievement.oc.redstoneCard=Regülatörü Tak. -achievement.oc.redstoneCard.desc=Daha tüpler ısınacak. -achievement.oc.redstoneIO=TRT -achievement.oc.redstoneIO.desc=İlk yayın birazdan başlayacak. -achievement.oc.robot="Gerginlik yaratma robot o robot." -achievement.oc.robot.desc="Robot musun sen?" "Evet." -achievement.oc.screen=Aç Kapa Çalışır. -achievement.oc.screen.desc=Gerçekten, kızıltaş sinyalleri etkiliyor. -achievement.oc.server=e-Devlet Kapısı -achievement.oc.server.desc=Ne varsa orada, bu bilgileri kim saklayacak. -achievement.oc.switch=Birini düzelt, diğerini boz. -achievement.oc.switch.desc=Telekomcular niye işlerini yapamıyor. -achievement.oc.tablet=Bu bir ilaç değildir. -achievement.oc.tablet.desc=Çocuklardan uzak tutun. İstenmeyen harcamalara neden olabilir. -achievement.oc.transistor=Düğmemtırak -achievement.oc.transistor.desc=Bizim radyodada vardı bunlardan. -achievement.oc.wirelessNetworkCard="Işınla bizi Scotty" -achievement.oc.wirelessNetworkCard.desc="Barış içinde size bir ileti getirdik." - -# Death messages. Note that the number of entries here must match the number -# set in the actual damage source in code. -death.attack.oc.nanomachinesOverload.1=%s elini çok sıkı tuttu. -death.attack.oc.nanomachinesOverload.2=%s kafayı yedi. -death.attack.oc.nanomachinesOverload.3=%s öldü. Nanomakine varmış diyorlar. -death.attack.oc.nanomachinesHungry.1=%s sizlere ömür. Nanomakineler diri diri yemiş. -death.attack.oc.nanomachinesHungry.2=%s nanomakinelerine bakmadı. -death.attack.oc.nanomachinesHungry.3=%s sindirildi. - -# NEI Integration -nei.options.inventory.oredict=Cevher Muadilleri Sözlüğü Adlarını Göster -nei.options.inventory.oredict.true=Evet -nei.options.inventory.oredict.false=Hayır -nei.usage.oc.Manual=Kılavuzu Aç - -# Waila Integration -option.oc.address=Adres -option.oc.componentName=Parça Adı -option.oc.energy=Enerji diff --git a/src/main/resources/assets/opencomputers/lang/tr_tr.json b/src/main/resources/assets/opencomputers/lang/tr_tr.json new file mode 100644 index 0000000000..095f2270a7 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/tr_tr.json @@ -0,0 +1,451 @@ +{ + "tile.oc.adapter": "Dönüştürücü", + "tile.oc.assembler": "Elektronik Birleştirici", + "tile.oc.cable": "Kablo", + "tile.oc.capacitor": "Sığaç", + "tile.oc.carpetedcapacitor": "Halılı Sığaç", + "tile.oc.case1": "Bilgisayar Kasası (1. Seviye)", + "tile.oc.case2": "Bilgisayar Kasası (2. Seviye)", + "tile.oc.case3": "Bilgisayar Kasası (3. Seviye)", + "tile.oc.casecreative": "Bilgisayar Kasası (Yaratıcı)", + "tile.oc.chameliumblock": "Şamelyum Küpü", + "tile.oc.charger": "Şarj Cihazı", + "tile.oc.disassembler": "Ayrıştırıcı", + "tile.oc.diskdrive": "Disket Sürücüsü", + "tile.oc.endstone": "End Taşı", + "tile.oc.geolyzer": "Jeolizer", + "tile.oc.hologram1": "Hologram Projektörü (1. Seviye)", + "tile.oc.hologram2": "Hologram Projektörü (2. Seviye)", + "tile.oc.keyboard": "Klavye", + "tile.oc.microcontroller": "Mikroişlemci", + "tile.oc.motionsensor": "Hareket Algılayıcı", + "tile.oc.netsplitter": "Ağ Bölücü", + "tile.oc.powerconverter": "Güç Dönüştürücü", + "tile.oc.powerdistributor": "Güç Dağıtıcı", + "tile.oc.print": "3B Çıktı", + "tile.oc.printer": "3B Yazıcı", + "tile.oc.raid": "RAID", + "tile.oc.redstone": "Kızıltaş G/Ç Küpü", + "tile.oc.relay": "Ağ Tamponu", + "tile.oc.robot": "Robot", + "tile.oc.robotafterimage": "Robot", + "tile.oc.screen1": "Ekran (1. Seviye)", + "tile.oc.screen2": "Ekran (2. Seviye)", + "tile.oc.screen3": "Ekran (3. Seviye)", + "tile.oc.rack": "Sunucu Rafı", + "tile.oc.transposer": "İletici", + "tile.oc.waypoint": "Yer İşareti", + "item.oc.abstractbuscard": "Soyut Veriyolu Kartı", + "item.oc.acid": "İspirto?", + "item.oc.alu": "Aritmetik Mantık Birimi (ALU)", + "item.oc.analyzer": "Analiz Aleti", + "item.oc.apu0": "Eklentili İşlemci (APU) (1. Seviye)", + "item.oc.apu1": "Eklentili İşlemci (APU) (2. Seviye)", + "item.oc.apu2": "Eklentili İşlemci (APU) (Yaratıcı)", + "item.oc.arrowkeys": "Ok Tuşları", + "item.oc.buttongroup": "Harf Takımı", + "item.oc.cardbase": "Ham Bilgisayar Kartı", + "item.oc.chamelium": "Şamelyum", + "item.oc.circuitboard": "Devre Kartı", + "item.oc.componentbus0": "Cihaz Veriyolu (1. Seviye)", + "item.oc.componentbus1": "Cihaz Veriyolu (2. Seviye)", + "item.oc.componentbus2": "Cihaz Veriyolu (3. Seviye)", + "item.oc.componentbus3": "Cihaz Veriyolu (Yaratıcı)", + "item.oc.controlunit": "Yönetim Birimi (CU)", + "item.oc.cpu0": "İşlemci (CPU) (1. Seviye)", + "item.oc.cpu1": "İşlemci (CPU) (2. Seviye)", + "item.oc.cpu2": "İşlemci (CPU) (3. Seviye)", + "item.oc.cuttingwire": "Kesme Teli", + "item.oc.datacard0": "Veri Kartı (1. Seviye)", + "item.oc.datacard1": "Veri Kartı (2. Seviye)", + "item.oc.datacard2": "Veri Kartı (3. Seviye)", + "item.oc.debugcard": "Hata Ayıklama Kartı", + "item.oc.debugger": "Ağ Hata Ayıklama Aleti", + "item.oc.diamondchip": "Elmas Kesiti", + "item.oc.disk": "Disk Bileşeni", + "item.oc.diskdrivemountable": "Disk", + "item.oc.drone": "Drone", + "item.oc.dronecase0": "Drone Kasası (1. Seviye)", + "item.oc.dronecase1": "Drone Kasası (2. Seviye)", + "item.oc.dronecase3": "Drone Kasası (3. Seviye)", + "item.oc.eeprom": "EEPROM", + "item.oc.floppydisk": "Disket", + "item.oc.graphicscard0": "Ekran Kartı (1. Seviye)", + "item.oc.graphicscard1": "Ekran Kartı (2. Seviye)", + "item.oc.graphicscard2": "Ekran Kartı (3. Seviye)", + "item.oc.harddiskdrive0": "Hard Disk (1. Seviye)", + "item.oc.harddiskdrive1": "Hard Disk (2. Seviye)", + "item.oc.harddiskdrive2": "Hard Disk (3. Seviye)", + "item.oc.hoverboots": "Uçma Botu", + "item.oc.inkcartridge": "Mürekkep Kartuşu", + "item.oc.inkcartridgeempty": "Mürekkep Kartuşu (Boş)", + "item.oc.internetcard": "İnternet Kartı", + "item.oc.interweb": "Ağ?", + "item.oc.ironnugget": "Demir Parçası", + "item.oc.linkedcard": "Bağlantılı Kart", + "item.oc.manual": "OpenComputers Kullanma Kılavuzu", + "item.oc.memory0": "Bellek (1. Seviye)", + "item.oc.memory1": "Bellek (1,5. Seviye)", + "item.oc.memory2": "Bellek (2. Seviye)", + "item.oc.memory3": "Bellek (2,5. Seviye)", + "item.oc.memory4": "Bellek (3. Seviye)", + "item.oc.memory5": "Bellek (3,5. Seviye)", + "item.oc.microchip0": "Entegre Devre (1. Seviye)", + "item.oc.microchip1": "Entegre Devre (2. Seviye)", + "item.oc.microchip2": "Entegre Devre (3. Seviye)", + "item.oc.microcontrollercase0": "Mikroişlemci Kasası (1. Seviye)", + "item.oc.microcontrollercase1": "Mikroişlemci Kasası (2. Seviye)", + "item.oc.microcontrollercase3": "Mikroişlemci Kasası (Yaratıcı)", + "item.oc.nanomachines": "Nanomakine", + "item.oc.networkcard": "Ağ Kartı", + "item.oc.numpad": "Tuş Takımı", + "item.oc.present": "Çam Sakızı...", + "item.oc.printedcircuitboard": "Devre Kartı (PCB)", + "item.oc.rawcircuitboard": "Ham Devre Kartı", + "item.oc.redstonecard0": "Kızıltaş Kartı (1. Seviye)", + "item.oc.redstonecard1": "Kızıltaş Kartı (2. Seviye)", + "item.oc.server0": "Sunucu (1. Seviye)", + "item.oc.server1": "Sunucu (2. Seviye)", + "item.oc.server2": "Sunucu (3. Seviye)", + "item.oc.server3": "Sunucu (Yaratıcı)", + "item.oc.tablet": "Tablet", + "item.oc.tabletcase0": "Tablet Kasası (1. Seviye)", + "item.oc.tabletcase1": "Tablet Kasası 500640(2. Seviye)", + "item.oc.tabletcase3": "Tablet Kasası (Yaratıcı)", + "item.oc.terminal": "Uzaktan Uçbirim", + "item.oc.terminalserver": "Uçbirim Sunucusu", + "item.oc.texturepicker": "Doku Seçici", + "item.oc.transistor": "Transistör", + "item.oc.upgradeangel": "Melek Eklentisi", + "item.oc.upgradebattery0": "Batarya Eklentisi (1. Seviye)", + "item.oc.upgradebattery1": "Batarya Eklentisi (2. Seviye)", + "item.oc.upgradebattery2": "Batarya Eklentisi (3. Seviye)", + "item.oc.upgradechunkloader": "Kesiti-yüklü-tut Eklentisi", + "item.oc.upgradecontainercard0": "Kart Yuvası (1. Seviye)", + "item.oc.upgradecontainercard1": "Kart Yuvası (2. Seviye)", + "item.oc.upgradecontainercard2": "Kart Yuvası (3. Seviye)", + "item.oc.upgradecontainerupgrade0": "Eklenti Yuvası (1. Seviye)", + "item.oc.upgradecontainerupgrade1": "Eklenti Yuvası (2. Seviye)", + "item.oc.upgradecontainerupgrade2": "Eklenti Yuvası (3. Seviye)", + "item.oc.upgradecrafting": "Üretim Eklentisi", + "item.oc.upgradedatabase0": "Veritabanı Eklentisi (1. Seviye)", + "item.oc.upgradedatabase1": "Veritabanı Eklentisi (2. Seviye)", + "item.oc.upgradedatabase2": "Veritabanı Eklentisi (3. Seviye)", + "item.oc.upgradeexperience": "Deneyim Eklentisi", + "item.oc.upgradegenerator": "Jeneratör Eklentisi", + "item.oc.upgradehover0": "Uçma Eklentisi (1. Seviye)", + "item.oc.upgradehover1": "Uçma Eklentisi (2. Seviye)", + "item.oc.upgradeinventory": "Envanter Eklentisi", + "item.oc.upgradeinventorycontroller": "Envanter Yönetimi Eklentisi", + "item.oc.upgradeleash": "Kayış Eklentisi", + "item.oc.upgrademf": "MFU", + "item.oc.upgradenavigation": "Yönbulma Eklentisi", + "item.oc.upgradepiston": "Piston Eklentisi", + "item.oc.upgradesign": "Tabela G/Ç Eklentisi", + "item.oc.upgradesolargenerator": "Güneş Enerjisi Eklentisi", + "item.oc.upgradetank": "Tank Eklentisi", + "item.oc.upgradetankcontroller": "Tank Yönetimi Eklentisi", + "item.oc.upgradetractorbeam": "Çekme Işını Eklentisi", + "item.oc.upgradetrading": "Ticaret Eklentisi", + "item.oc.wirelessnetworkcard0": "Kablosuz Ağ Kartı (1. Seviye)", + "item.oc.wirelessnetworkcard1": "Kablosuz Ağ Kartı (2. Seviye)", + "item.oc.worldsensorcard": "Dünya Algılayıcı Kartı", + "item.oc.wrench": "Tornanahtar", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.Drone": "Drone", + "oc:gui.Analyzer.Address": "§6Adres§f: %s", + "oc:gui.Analyzer.AddressCopied": "Adres panoya kopyalandı", + "oc:gui.Analyzer.ChargerSpeed": "§6Şarj hızı§f: %s", + "oc:gui.Analyzer.ComponentName": "§6Parça adı§f: %s", + "oc:gui.Analyzer.Components": "§6Bağlı parça sayısı§f: %s", + "oc:gui.Analyzer.CopyToClipboard": "Panoya kopyalamak için tıklayın.", + "oc:gui.Analyzer.LastError": "§6Son hata§f: %s", + "oc:gui.Analyzer.RobotName": "§6Adı§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6Sahibi§f: %s", + "oc:gui.Analyzer.RobotXp": "§6Deneyimi§f: %s (Seviye %s)", + "oc:gui.Analyzer.StoredEnergy": "§6Depoladığı enerji§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6Maksimum enerji miktarı§f: %s", + "oc:gui.Analyzer.Users": "§6Kullanıcılar§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6Sinyal gücü§f: %s", + "oc:gui.Assembler.Collect": "Çıktıyı al", + "oc:gui.Assembler.Complexity": "Karmaşıklık: %s/%s", + "oc:gui.Assembler.InsertCase": "Kasa koyun", + "oc:gui.Assembler.InsertCPU": "İşlemci koyun", + "oc:gui.Assembler.InsertRAM": "Bellek koyun", + "oc:gui.Assembler.Progress": "İlerleme: %s%% (%s)", + "oc:gui.Assembler.Run": "Birleştir", + "oc:gui.Assembler.Warning.BIOS": "BIOS", + "oc:gui.Assembler.Warning.GraphicsCard": "Ekran Kartı", + "oc:gui.Assembler.Warning.Inventory": "Envanter Eklentisi", + "oc:gui.Assembler.Warning.Keyboard": "Klavye", + "oc:gui.Assembler.Warning.OS": "Başlangıç Bölümü", + "oc:gui.Assembler.Warning.Screen": "Ekran", + "oc:gui.Assembler.Warnings": "§eUyarı§7: Önerilen parçalar eksik.", + "oc:gui.Chat.NewVersion": "Yeni bir sürüm çıktı: %s", + "oc:gui.Chat.TextureName": "§7Doku adı §a%s§f.", + "oc:gui.Chat.WarningClassTransformer": "Sınıf dönüştürücü çalışırken §chatalar§f oluştu. Lütfen bunu mod yazarlarına (bütün!) FML §alatest.log§f/§afml-server-latest.log§f kayıt dosyasıyla birlikte gönderiniz. Şimdiden teşekkür ederiz.", + "oc:gui.Chat.WarningFingerprint": "§cUYARI§f - Parmakizi uyuşmazlığı! '§a%s§f' beklerken '§e%s§f' bulduk. Eğer karılmamış sürümünü kullanan bir mode yazarı değilseniz OpenComputers modunu yeniden indirmeniz §lşiddetle§f tavsiye edilir; çünkü elinizdeki JAR dosyası ile oynanmış olabilir.", + "oc:gui.Chat.WarningLink": "Bağlantı açılamadı: %s", + "oc:gui.Chat.WarningLuaFallback": "Orijinal Lua kütüphaneleri bulunamadı ve bilgisayarlar durumlarını koruyamayacak. Bölümler yeniden yüklenince bilgisayarlar yeniden başlayacak. (Yedek kütüphaneler kullanılıyor)", + "oc:gui.Chat.WarningProjectRed": "OpenComputers'ı desteklemeyen bir Project: Red sürümünü kullanıyorsunuz. Project: Red'i güncellemeyi deneyin.", + "oc:gui.Chat.WarningRecipes": "Bir veya birden fazla tarifi yüklerken hata oluştu. Bazı nesneler üretilemeyebilir. Daha fazla bilgi için kayıt defteri dosyanızı bakın.", + "oc:gui.Drive.Managed": "Denetimli", + "oc:gui.Drive.Unmanaged": "Denetimsiz", + "oc:gui.Drive.Warning": "§lUyarı§r: kip değiştirmek disk üzerindeki bütün verinin kaybına sebep olur.", + "oc:gui.Error.ComponentOverflow": "Bilgisayara çok parça takılı.", + "oc:gui.Error.InternalError": "İçsel bir hata, lütfen kayıt defterine bakın. Bu büyük ihtimalle bir yazılım sorunu.", + "oc:gui.Error.NoCPU": "Bilgisayarın işlemcisi yok.", + "oc:gui.Error.NoEnergy": "Güç yeterli değil.", + "oc:gui.Error.NoRAM": "Bilgisayarda bellek yok.", + "oc:gui.Error.OutOfMemory": "Bellek taştı.", + "oc:gui.Manual.Blocks": "OpenComputers Küpler", + "oc:gui.Manual.Home": "Ev", + "oc:gui.Manual.Items": "OpenComputers Nesneler", + "oc:gui.Manual.Warning.BlockMissing": "Küp yok.", + "oc:gui.Manual.Warning.ImageMissing": "Resim bulunamadı.", + "oc:gui.Manual.Warning.ItemMissing": "Nesne yok.", + "oc:gui.Manual.Warning.OreDictMissing": "Cevher Muadilleri Sözlüğü yok.", + "oc:gui.Raid.Warning": "§4Disk eklemek onu siler.\nDisk çıkarmak RAID'i siler.", + "oc:gui.Robot.Power": "Güç", + "oc:gui.Robot.TurnOff": "Kapat", + "oc:gui.Robot.TurnOn": "Aç\n§7Hata çözmek için analiz aletini kullanın.§r", + "oc:gui.Rack.Back": "Arka", + "oc:gui.Rack.Bottom": "Alt", + "oc:gui.Rack.Left": "Sol", + "oc:gui.Rack.None": "Hiç", + "oc:gui.Rack.Right": "Sağ", + "oc:gui.Rack.Enabled": "Aktif", + "oc:gui.Rack.Disabled": "İnaktif", + "oc:gui.Rack.Top": "Üst", + "oc:gui.Switch.PacketsPerCycle": "Paket / devir", + "oc:gui.Switch.QueueSize": "Sıra Uzunluğu", + "oc:gui.Switch.TransferRate": "Devir hızı", + "oc:gui.Terminal.InvalidKey": "Geçersiz anahtar. Büyük ihtimalle başka bir uçbirim sunuzuya bağlandı.", + "oc:gui.Terminal.OutOfRange": "Sinyal yok.", + "oc:container.adapter": "Dönüştürücü", + "oc:container.case": "Bilgisayar", + "oc:container.charger": "Şarj Aleti", + "oc:container.disassembler": "Ayrıştırıcı", + "oc:container.diskdrive": "Disket Sürücüsü", + "oc:container.printer": "Yazıcı", + "oc:container.raid": "RAID", + "oc:container.relay": "Ağ Tamponu", + "oc:container.server": "Sunucu", + "oc:container.rack": "Sunucu Rafı", + "oc:container.tabletwrapper": "Tablet", + "key.opencomputers.clipboardPaste": "Panodan Yapıştır", + "oc:tooltip.abstractbuscard": "LIP paketleri alıp ileterek §fStargateTech 2§7'in soyut veriyolu ile iletişim kurmanızı sağlar.", + "oc:tooltip.acid": "Zehirli, alkol kokan sıvımtırak bir şey. Belki askerde bazı manyak herifler kafayı bulmak için içer. Başka kullanım alanları da olabilir.", + "oc:tooltip.adapter": "Parça olmayan blokları (örneğin \"vanilla\" bloklar veya diğer modların bloklarını) kumanda etmek için kullanılır.", + "oc:tooltip.alu": "Siz yorulmayın diye sizin için işlem yapar. Belki böylesi daha iyidir.", + "oc:tooltip.analyzer": "Blokların §fadresi§7 ve §fparça ismi§7 gibi özelliklerini gösterir.\nAyrıca bilgisayarın beklenmedik bir şekilde kapanmasına sebep olan hatayı da gösterir.", + "oc:tooltip.apu": " Ekran kartı olan bir işlemci, bir kart yuvasına daha ihtiyacınız olursa diye.\nDesteklenen parçalar: §f%s§7\nMaksimum çözünürlük: §f%sx%s§7\nMaksimum renk derinliği: §f%s§7\nİşlem/tick: §f%s§7", + "oc:tooltip.assembler": "Bilgisayar parçalarından robot ve başka cihazları üretmenize yarar.", + "oc:tooltip.cable": "Blokları bağlamanın ucuz bir yolu.", + "oc:tooltip.capacitor": "Daha sonra kullanılmak üzere enerji depolar. Çok hızlı şarj ve desarj olabilir.", + "oc:tooltip.carpetedcapacitor": "Daha sonra kullanılmak üzere enerji depolar. Çok hızlı şarj ve desarj olabilir. Bir Oselo veya Koyun üstünde yürürse şarj olur.", + "oc:tooltip.cardbase": "Adı üstünde, tüm bilgisayar kartlarının en basit yapıtaşı.", + "oc:tooltip.case": "Bilgisayar kasası bilgisayarın yapıtaşıdır ve bilgisayarın §fkartlarını§7, §fbelleğini§7 ve §fsürücülerimi§7 bünyesimde barındırır.\nYuvalar: §f%s§7", + "oc:tooltip.chamelium": "3B çıktılar için hammaddedir. Yutmayınız, körlük ve geçici bilinç kaybına sebep olabilir.", + "oc:tooltip.chameliumblock": "Hoş ve temiz. 3B çıktılarda renkli şekiller yaratmak veya üssünüzü temiz ve renkli bir blokla dekore etmek için kullanılabilir.", + "oc:tooltip.charger": "Sığaçlardan takındaki robotlara ve dronlara enerji aktarır. Aktarım hızı gelen §fkızıltaş sinyaline§7 bağlıdır; tam güç tam hızla şarj olması, hiç sinyal olmaması ise şarj olmaması demektir. Tabletleri de şarj etmek, hatta sürücülerine erişmek için kullanılabilir.", + "oc:tooltip.circuitboard": "İşte şimdi yol alıyoruz. İşleme tabi tutularak devre kartı elde edilebilir.", + "oc:tooltip.controlunit": "Bu birim... yönetiyor işte. İşlemciye ihtiyacın var o yüzden önemli, değil mi?", + "oc:tooltip.componentbus": "Bu eklenti sunucuların aynı anda daha çok parça ile bağlantı kurmasını sağlar, işlemciler gibi.\nDesteklenen parçalar §f%s§7", + "oc:tooltip.cpu": "Her bilgisayara lazım. Saati biraz istikrarsız ama cep saatinden o kadar oluyor. Çok sarsma.\nDesteklenen parçalar: §f%s§7", + "oc:tooltip.cpu.Architecture": "Mimari: §f%s§7", + "oc:tooltip.cuttingwire": "Kil blokları devre kartı şekline sokmak için kullanılır. Tek kullanımda kopar. Ne iğrenç bir alet bu.", + "oc:tooltip.datacard0": "\"hashing\", \"deflate\"/\"inflate\" gibi birkaç gelişmiş algoritma sunar.", + "oc:tooltip.datacard1": "\"hashing\", \"deflate\"/\"inflate\", AES şifreleme gibi birkaç gelişmiş algoritma sunar.", + "oc:tooltip.datacard2": "\"hashing\", \"deflate\"/\"inflate\", AES şifreleme, eliptik eğri kriptografisi gibi birkaç gelişmiş algoritma sunar.", + "oc:tooltip.debugcard": "Test etmeyi kolaylaştıran, dünyayı manüpile eden Yaratıcı mod aracı. Yetişkin denetimi altında kullanın.", + "oc:tooltip.debugger": "OpenComputers'ın iç ağının hata ayıklama bilgisini toplamak için kullanılır. Sadece bir geliştirici isterse kullanınız.", + "oc:tooltip.diamondchip": "Parıltılı bir elmasın naçiz bir parçası. Asla eskisi gibi olamayacak.", + "oc:tooltip.disassembler": "Nesneleri ihtiva ettiği parçalarına ayrıştırır. §lUyarı§7: ayrışan parçaların ayrışma sürecinde %%%s bozulma olasılığı vardır.", + "oc:tooltip.disk": "Daimi veri depolama cihazları yapılabilen ilkel veri saklama dairesi.", + "oc:tooltip.diskdrive.CC": "ComputerCraft disketler §açalışır§7.", + "oc:tooltip.diskdrive": "Disket okuma ve yazmaya yarar. Daha sonra disket takmak için robotlara da takılabilir.", + "oc:tooltip.diskdrivemountable": "Normal bir sürücüyle aynı işlevi görür fakat bir sunucu rafına takılmalıdır.", + "oc:tooltip.diskusage": "Disk kullanımı: %s/%s Byte", + "oc:tooltip.diskmodemanaged": "Kip: Denetimli", + "oc:tooltip.diskmodeunmanaged": "Kip: Denetimsiz", + "oc:tooltip.drone": "Dronlar hafif, hızlı, az yük kapasiteli uçan cihazlardır.", + "oc:tooltip.dronecase": "Bu kasa birleştirici ile Drone yapmak için kullanılır. Sınırlı parça için alanı var ve end taşı ile güçlendirilmiş uçma kabiliyeti var.", + "oc:tooltip.eeprom": "Elektrikle silinebilir, programlanabilir salt okunur hafıza. Bilgisayarların çalışması için gerekli BIOS kodunu içerir.", + "oc:tooltip.fakeendstone": "Neredeyse aynısı, bu da havalanmaya meyilli.", + "oc:tooltip.geolyzer": "Yakındaki blokların sertliğini ölçmeye yarar. Bu bilgi cevher bulmak için bölgenin holgramını yapmaya yarayabilir.", + "oc:tooltip.graphicscard": "Ekranları güzel bilgilerle doldurur.\nAzami Çözünürlük: §f%sx%s§7\nAzami renk derinliği: §f%s§7\nİşlem/tick: §f%s§7", + "oc:tooltip.hoverboots": "Daha yükseğe sıçra, daha derine in, daha iyi yürü. Hepsi Uçan Bot (TM) sayesinde.", + "oc:tooltip.inkcartridge": "3B yazıcılara mürekkep koymak için kullanılır. Nedense makineye takılı kalmıyor.", + "oc:tooltip.inkcartridgeempty": "Yazıcının kartuşu yine birmiş. Mürekkebi doldurabilirsin. Ya da at gitsin. Nasıl olsa bir daha aynı yazmaz.", + "oc:tooltip.internetcard": "Bu kart ile gerçekten internete bağlanıp, TCP üzerinden HTTP istemlerinde bulunabilirsiniz.", + "oc:tooltip.interweb": "Tebrikler, bir ağ (?) kazandınız. Internete bununla bağlanabilirsiniz. Trollerin seviyesine inmmeyin.", + "oc:tooltip.ironnugget": "Demirden kopan bir parça, başka nasıl açıklayayım.", + "oc:tooltip.keyboard": "Yazı yazmak için ekranlara takılabilir.", + "oc:tooltip.hologram0": "Bilgisayarla kumanda edilen, voksel tabanlı yapıları göstermek için kullanılan hacimsel ekran.\nÇözünürlük: §f48x32x48§7\nAzami Ölçek: §f3x§7\nRenk derinliği: §fMonokrom§7", + "oc:tooltip.hologram1": "Bilgisayarla kumanda edilen, voksel tabanlı yapıları göstermek için kullanılan hacimsel ekran.\nÇözünürlük: §f48x32x48§7\nAzami Ölçek: §f3x§7\nRenk derinliği: §f3 Renkli§7", + "oc:tooltip.linkedcard": "Bunlar çiftler halinde üretilir ve sadece partneriyle iletişim kurarlar. İletişimleri mesafeyi ve boyutları engel tanımaz fakat çok güç ister.", + "oc:tooltip.linkedcard_channel": "§8Kanal: %s§7", + "oc:tooltip.manual": "OpenComputers hakkında ihtiyaç duyabileceğiniz her bilgi ve daha fazlası. Hem de sadece ... §ofiyatı öğrenmek için R'ye basın§7.", + "oc:tooltip.memory": "Bilgisayarların çalışması için gerekli. Ne kadar çok belleğiniz varsa o kadar karmaşık programlar çalıştırabilirsiniz.", + "oc:tooltip.microchip": "Siyah elektrikle çalışan zımbırtılar. Neden kızıltaşla çalıştıkları beni aşıyor.", + "oc:tooltip.microcontroller": "Mikroişlemciler bilgisayarların en asgari biçimi. Görev odaklıdırlar ve EEPROM'larında gelen tek bir programla çalışırlar.\n§cHarici parçalarla bağlantı kuramazlar.§7", + "oc:tooltip.microcontrollercase": "Mikroişlemcilerin temel bileşeni. Mikroişlemci yapmak için bir birleştirici kullanın ve başka parçalar ekleyin.", + "oc:tooltip.motionsensor": "Yakındaki canlıların hareketini algılar. Çalışması için canlılar görüş açısında olmalıdır.", + "oc:tooltip.nanomachines": "Kumanda birimi ve tüketilmek üzere bir sürü nanomakine, tabi sende o mide varse.", + "oc:tooltip.networkcard": "Uzaktaki, birbirine başka bloklarla bağlı (örneğin kablolarla) bilgisayarların birbirlerine mesajlar göndererek iletişim kurmasını sağlar.", + "oc:tooltip.poweracceptor": "Enerji dönüşüm hızı: §f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§fBuildCraft MJ'si§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§fFactorization Yükü§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fIndustrialCraft² EU'su§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§fMekanism Joule'ü§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fThermal Expansion RF'i§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fResonant Engine Coulomb'u§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "Başka modların enerjilerini OpenComputers'ın kendi enerji birimine dönüştürür. Dönüşüm oranları:", + "oc:tooltip.powerdistributor": "Farklı ağlara enerji dağıtır. Ayrı kalması gereken alt-ağlara dönüştürücüden gelen enerjiyi dağıtmak için bire bir.", + "oc:tooltip.present": "... çoban armağanı. Verdiğimiz rahatsızlıktan dolayı. Hediyeyi açarak §kganimetlere§7 sahip olabilirsiniz.\n§8Doğru zamanda OpenComputers parçaları üreterek hediye kazanabilirsiniz.§7", + "oc:tooltip.print.BeaconBase": "§8Fener tabanı olarak işlev görür.", + "oc:tooltip.print.LightValue": "§8Işınan ışık: %s.", + "oc:tooltip.print.RedstoneLevel": "§8Kızıltaş çıktısı: %s.", + "oc:tooltip.printedcircuitboard": "Bellek, bilgisayar kartları vb.nin yapı taşı.", + "oc:tooltip.printer": "Kullanıcı tanımlı nesnelerin şamelyum ve mürekkep kullanılarak basılmasını sağlar. Bir bilgisayar tarafından yönetilmelidir. Bazı sebeplerden dolayı, çocuklardan uzak tutun.", + "oc:tooltip.raid": "Birden fazla diskin tek bir dosya sistemi altında birleştirilip bağlı tüm bilgisayarlar tarafından kullanılmasını sağlar.", + "oc:tooltip.rawcircuitboard": "Herhangi bir fırında kurutulabilir.", + "oc:tooltip.redstone": "Bloğun çevresinde kızıltaş iletimi ve çevresinden kızıltaş alıgalma yapabilir. Bağlı herhangi bir bilgisayar kumanda edebilir. Harici bir kızıltaş kartı gibi davranır.", + "oc:tooltip.redstonecard.ProjectRed": "§fProject: Red§7 §adestekli§7.", + "oc:tooltip.redstonecard.RedLogic": "§fRedLogic§7 §adestekli§7.", + "oc:tooltip.redstonecard.RedNet": "§fRedNet§7 §adestekli§7.", + "oc:tooltip.redstonecard.WirelessCBE": "§fWireless Redstone (ChickenBones)§7 §adestekli§7.", + "oc:tooltip.redstonecard.WirelessSV": "§fWireless Redstone (SlimeVoid)§7 §adestekli§7.", + "oc:tooltip.redstonecard": "Bilgisayarın veya robotun çevresine kızltaş sinyali iletimesini ve çevresinden kızıltaş sinyalı algılamasını sağlar.", + "oc:tooltip.relay": "Farklı ağları birbirine bağlamaya yarar. Sadece ağ mesajları iletilir, parçalar görünmez. Bunu Ağ kartlarını kullanırken bilgisayarları birbirinden izole etmek için kullanabilirsiniz.", + "oc:tooltip.robot": "Bilgisayarların aksine robotlar oyuncular gibi dünyada hareket edebilir ve ona değişiklikler yapabilir.\n§cHarici parçalara bağlanamaz.§7", + "oc:tooltip.robot_level": "§fSeviye§7: §a%s§7", + "oc:tooltip.robot_storedenergy": "§fDepolu enerji§7: §a%s§7", + "oc:tooltip.screen": "Yazı göster, kasadaki bir ekran kartı aracılığıyla.\nAzami çözünürlük: §f%sx%s§7\nAzami renk derinliği: §f%s§7", + "oc:tooltip.server": "Bu bir sunucu. Bundan çokça olabilir fakat bu (bir bilgisayar gibi) başka parçalarla geliştirilebilir. Sunucu rafına takılarak çalıştırılabilir.", + "oc:tooltip.server.Components": "Takılı Parçalar:", + "oc:tooltip.rack": "4 sunucunun veya rafa konulabilen parçaların takılmasını sağlar.", + "oc:tooltip.tablet": "Lua ile eğlence için bir tablet bilgisayar. Çömelirken aktifleştirirseniz kapanmaya sorlarsınız.", + "oc:tooltip.tabletcase": "Basit bir tablet kasası. Bir birleştirici ve başka parçalar ile bir tablet yapabilirsiniz..", + "oc:tooltip.terminal": "Menzili içinde bir sunucuyu uzaktan kumanda etmenize yarar. Taşınabilir ekran ve klavye gibi davranır. Shift+Sağ-Tık ile raftaki bir sunucuya bağlayabilirsiniz.", + "oc:tooltip.terminalserver": "Uzaktan Uçbirimin yöneticisi. Sanal bir ekranı ve klavyesi var.", + "oc:tooltip.texturepicker": " Bu alet, 3B yazıcıda şekil tanımlamak üzere bir bloğun yüzeyini ifade eden bir metin gösterir. Kesinlikle dokunun ismi değil. Sana yalan borcum mu var?", + "oc:tooltip.tier": "§8%s. Seviye", + "oc:tooltip.netsplitter": "Ayarlanabilir bir bağlantı noktası gibi davranır. Her yüzün bağlantısı bir İngiliz anahtarı ile değiştirilebilir. Her yüzün bağlantısı bir kızıltaş sinyali ile tersine dönüştürülebilr.", + "oc:tooltip.toolong": "Şuna basılı tutarak daha detaylı bilgi alabilirsiniz: [§f%s§7]", + "oc:tooltip.transistor": "Çoğu bilgisayar parçasının basit bir bileşeni. Biraz yamulmuş ama iş görür.", + "oc:tooltip.transposer": "Bitişiğindeki envanterler arasında katı ve sıvı değişimini sağlar.", + "oc:tooltip.upgradeangel": "Robotlara boşlukta (tutunacak yer yokken) blok koyma yetisi sağlar.", + "oc:tooltip.upgradebattery": "Cihazın depolayabileceği enerji miktarını arttırır. Böylece cihaz şarj olmadan daha uzun süre çalışabilir.\nKapasite: §f%s§7", + "oc:tooltip.upgradechunkloader": "Robot tek başına ormana giderse ve onu kimse görmezse hareket eder mi? Bu eklenti çalıştığından emin olur. Bir bölümü(16x16x256) sürekli yüklü tutar fakat sürekli enerji harcar.", + "oc:tooltip.upgradecontainercard": "Bu yuva birleştirilmiş cihazda kartların rahatlıkla takılıp çıkarılmasını sağlar.\nAzami Seviye: §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "Bu yuva birleştirilmiş cihazda eklentilerin rahatlıkla takılıp çıkarılmasını sağlar.\nAzami Seviye: §f%s§7", + "oc:tooltip.upgradecrafting": "Robotun envanterinin sol üst köşesini çalışma masası gibi kullanmasını sağlar. Nesnelerin tarife göre yerleşmesi şarttır.", + "oc:tooltip.upgradedatabase": "Bu eklenti deste bilgisinin başka parçalar tarafından kullanılmak üzere saklanmasını sağlar.\nDesteklenen satır sayısı: §f%s§7", + "oc:tooltip.upgradeexperience": "Bu eklenti çeşitli eylemler aracalığıyla robotların deneyim kazanmasını sağlar. Robotlar ne kadar deneyimliyse o kadar enerji depolayabilir, o kadar hızlı blok toplayabilir ve aletleri o kadar etkili kullanabilir.", + "oc:tooltip.upgradegenerator": "Yolda yakıttan enerji üretimini sağlar. Yakıtları enerji değerlerine göre enerji üretmek için kullanır.\n§fVerimlilik§7: §a%s%%§7", + "oc:tooltip.upgradehover": "Bu eklenti robotun duvar tırmanmak zorunda kalmadan daha yükseğe çıkmasını sağlar.\nAzami irtifa: §f%s§7", + "oc:tooltip.upgradeinventory": "Bu eklenti bir robota veya drona envanter sağlar. Bu olmadan nesne tutamazlar.", + "oc:tooltip.upgradeinventorycontroller": "Bu eklenti robotların ve dronların harici envanterlerle iletişim kurmasını ve onlardaki aletlerle kendi aletini değişmesini sağlar.", + "oc:tooltip.upgrademf": "Dönüştürücülerin bitişiğinde olmadığı nesnelerle iletişim kurmasını sağlar.", + "oc:tooltip.upgrademf.Linked": "§fBağlantı kuruldu§7", + "oc:tooltip.upgrademf.Unlinked": "§fBağlantı yok§7", + "oc:tooltip.upgradeleash": "Drone gibi bazı cihazların belediye görevlilerine sataş...-özür dilerim. Bu cihaz aslında canlı(lar)ı bağlamak için kullanılıyormuş. İlğinç.", + "oc:tooltip.upgradenavigation": "Cihazın yönünü ve yerini tespit etmek için kullanılır. Yer bilgisi eklentiyi üretirken kullanılan haritanın merkez noktasına göredir.", + "oc:tooltip.upgradepiston": "Bu eklenti çok itici. Piston gibi blokları hareket ettirmeye yarar. Canlıları ve partikülleri hareket ettir§lmez§7.", + "oc:tooltip.upgradesign": "Tabelalardan yazı okumayı ve onlara yazı yazmayı sağlar.", + "oc:tooltip.upgradesolargenerator": "Güneşten enerji üretimini sağlar. Gökyüzü görüş açısında olmalıdır. Bir Stirling motorunun %%%s katı hızı kadar hızlı enerji üretebilir.", + "oc:tooltip.upgradetank": "Robotlara ve dronlara sıvı depolama alanı sağlar. Bu olmadan sıvı depolayamazlar.", + "oc:tooltip.upgradetankcontroller": "Bu eklenti robotlara ve dronlara harici sıvı depoları ile iletişim yeteneği sağlar. Harici depodan dahiliye, dahiliden hariciye sıvı iletimi sağlar.", + "oc:tooltip.upgradetractorbeam": "Nesne mıknatısı adı verilen çok gelişmiş bir teknolojiti edinin. Cihazın 3 block menzilinden nesneleri almasını sağlar.", + "oc:tooltip.waypoint": "Yönbulma eklentisi olan cihazlar için referans noktası oluşturur.", + "oc:tooltip.wirelessnetworkcard": "Normal ağ mesajlarının yanı sıra kablosuz ağ mesajlarının iletimini sağlar. §fSinyal gücünü§7 ayarlayarak mesajların ne kadar uzağa iletildiğini kontrol edebilirsiniz. Yüksek sinyal gücü daha çok enerji tüketir.", + "oc:tooltip.worldsensorcard": "Dünya hakkında yerçekimi ve nefes alınabilir bir atmosferi olup olmadığı gibi bilgileri toplar. Bilgiler kesin değildir. Üretici firma karttan edilen bilgilere göre verilen kararlar sonucu oluşan maddi ve manevi hiçbir hasardan sorumlu değildir. Avukatlarımız var. Paramız da. Denemeyi aklınızdan bile geçirmeyin.", + "oc:tooltip.Wrench": "İngiliz anahtarı tornavida karışımı bir şey. Öğrenmesi basit, ustalaşması zor.", + "achievement.oc.adapter": "Tak-Çalıştır", + "achievement.oc.adapter.desc": "Diğer modların ve elbette vanilla Minecraft blokları ile iletişim kur.", + "achievement.oc.assembler": "Harika", + "achievement.oc.assembler.desc": "Dünyayı ele geçirme vakti.", + "achievement.oc.cable": "Temiz Kablo", + "achievement.oc.cable.desc": "Patentli dolanma önleyici teknolojisi ile.", + "achievement.oc.capacitor": "Piller Ürüne Dahildir.", + "achievement.oc.capacitor.desc": "Durduramazsın.", + "achievement.oc.card": "Kredi Kartı Geçerlidir.", + "achievement.oc.card.desc": "Sizin için. Kesinlikle bir art niyetimiz yok.", + "achievement.oc.case": "Yangın Durumunda ...", + "achievement.oc.case.desc": "Çünkü küp kasalar en iyisi.", + "achievement.oc.charger": "Haydi şu işi bitirelim.", + "achievement.oc.charger.desc": "Şarj etsene seni... Kızıltaş sinyalini unutmuşum.", + "achievement.oc.chip": "En Küçüğünden Lütfen", + "achievement.oc.chip.desc": "Çünkü tüpler eskide kaldı.", + "achievement.oc.cpu": "Modifiye", + "achievement.oc.cpu.desc": "Haydi bu makineyi biraz zorlayalım.", + "achievement.oc.disassembler": "Ali Yazar, Veli Bozar", + "achievement.oc.disassembler.desc": "Nasıl olsa Sarı Çizmeli Mehmet Ağa bir gün öder hesabı.", + "achievement.oc.diskDrive": "Dönmedolap", + "achievement.oc.diskDrive.desc": "Az alan, güzel ses.", + "achievement.oc.drone": "Su gibi git...", + "achievement.oc.drone.desc": "... su gibi gel. Pahalısın lazımsın bize.", + "achievement.oc.eeprom": "Ya ben, ya hiç!", + "achievement.oc.eeprom.desc": "Bilgisayar için, önemli bir parça.", + "achievement.oc.floppy": "Güneş Tutulması", + "achievement.oc.floppy.desc": "Hepsini bozduk 1999'da.", + "achievement.oc.geolyzer": "Zonguldak", + "achievement.oc.geolyzer.desc": "Toprak ne ki, yeri bir metre kaz kömür çıkıyor.", + "achievement.oc.graphicsCard": "Yeni Nesil", + "achievement.oc.graphicsCard.desc": "Döviz kuru düşseydi fakir kalmazdım.", + "achievement.oc.hdd": "Hıyar Domates Dirhem", + "achievement.oc.hdd.desc": "Yanlış oldu, bekle dilimin ucunda.", + "achievement.oc.hologram": "Gelecek Boyut", + "achievement.oc.hologram.desc": "2B'tan sıkıldın mı?", + "achievement.oc.keyboard": "TozMıknatısı3000", + "achievement.oc.keyboard.desc": "Odanıza alın, odanız tertemiz olsun*. *TozMıknatısı300 dışında.", + "achievement.oc.microcontroller": "Kardeş", + "achievement.oc.microcontroller.desc": "Bilgisayarın küçük kardeşi.", + "achievement.oc.motionSensor": "Tuvalet Kabusu", + "achievement.oc.motionSensor.desc": "İşerken ışık söner mi acaba?", + "achievement.oc.networkCard": "Feysbuk", + "achievement.oc.networkCard.desc": "Hep birlikte kimsenin takmadığı şeyleri paylaşıp sosyal olduğumuzu sanıyoruz.", + "achievement.oc.openOS": "iŞlEtİm SiStEmİ NeY?", + "achievement.oc.openOS.desc": "Bilgisayarcıya git format atsın ablacım.", + "achievement.oc.powerDistributor": "Hayat Paylaşınca Güzel", + "achievement.oc.powerDistributor.desc": "Reklam yapmıyoruz. Güzel sözün telif hakkı mı olur?", + "achievement.oc.rack": "\"Bizim salondaki raf olur mu?\"", + "achievement.oc.rack.desc": "Tartmaz bir kere.", + "achievement.oc.raid": "Yerim Kalmadı.", + "achievement.oc.raid.desc": "Ne kadar çok \"aile fotoğrafı\"n varsa artık.", + "achievement.oc.ram": "Seçici Hatıra", + "achievement.oc.ram.desc": "Nedense sevdiklerimi daha çok hatırlıyorum.", + "achievement.oc.redstoneCard": "Regülatörü Tak.", + "achievement.oc.redstoneCard.desc": "Daha tüpler ısınacak.", + "achievement.oc.redstoneIO": "TRT", + "achievement.oc.redstoneIO.desc": "İlk yayın birazdan başlayacak.", + "achievement.oc.robot": "\"Gerginlik yaratma robot o robot.\"", + "achievement.oc.robot.desc": "\"Robot musun sen?\" \"Evet.\"", + "achievement.oc.screen": "Aç Kapa Çalışır.", + "achievement.oc.screen.desc": "Gerçekten, kızıltaş sinyalleri etkiliyor.", + "achievement.oc.server": "e-Devlet Kapısı", + "achievement.oc.server.desc": "Ne varsa orada, bu bilgileri kim saklayacak.", + "achievement.oc.switch": "Birini düzelt, diğerini boz.", + "achievement.oc.switch.desc": "Telekomcular niye işlerini yapamıyor.", + "achievement.oc.tablet": "Bu bir ilaç değildir.", + "achievement.oc.tablet.desc": "Çocuklardan uzak tutun. İstenmeyen harcamalara neden olabilir.", + "achievement.oc.transistor": "Düğmemtırak", + "achievement.oc.transistor.desc": "Bizim radyodada vardı bunlardan.", + "achievement.oc.wirelessNetworkCard": "\"Işınla bizi Scotty\"", + "achievement.oc.wirelessNetworkCard.desc": "\"Barış içinde size bir ileti getirdik.\"", + "death.attack.oc.nanomachinesOverload.1": "%s elini çok sıkı tuttu.", + "death.attack.oc.nanomachinesOverload.2": "%s kafayı yedi.", + "death.attack.oc.nanomachinesOverload.3": "%s öldü. Nanomakine varmış diyorlar.", + "death.attack.oc.nanomachinesHungry.1": "%s sizlere ömür. Nanomakineler diri diri yemiş.", + "death.attack.oc.nanomachinesHungry.2": "%s nanomakinelerine bakmadı.", + "death.attack.oc.nanomachinesHungry.3": "%s sindirildi.", + "nei.options.inventory.oredict": "Cevher Muadilleri Sözlüğü Adlarını Göster", + "nei.options.inventory.oredict.true": "Evet", + "nei.options.inventory.oredict.false": "Hayır", + "nei.usage.oc.Manual": "Kılavuzu Aç", + "option.oc.address": "Adres", + "option.oc.componentName": "Parça Adı", + "option.oc.energy": "Enerji" +} diff --git a/src/main/resources/assets/opencomputers/lang/zh_CN.lang b/src/main/resources/assets/opencomputers/lang/zh_CN.lang deleted file mode 100644 index de254f0db7..0000000000 --- a/src/main/resources/assets/opencomputers/lang/zh_CN.lang +++ /dev/null @@ -1,479 +0,0 @@ -# OpenComputer -# This is the Simplified Chinese file for localizations. -# Use [nl] to for a line break. 使用[nl]换行。 - -# Blocks -tile.oc.adapter.name=适配器 -tile.oc.assembler.name=装配器 -tile.oc.cable.name=线缆 -tile.oc.capacitor.name=电容 -tile.oc.carpetedcapacitor.name=踩踏发电电容 -tile.oc.case1.name=基础机箱 -tile.oc.case2.name=高级机箱 -tile.oc.case3.name=超级机箱 -tile.oc.casecreative.name=创造模式机箱 -tile.oc.chameliumblock.name=变色块 -tile.oc.charger.name=充电器 -tile.oc.disassembler.name=拆解器 -tile.oc.diskdrive.name=软盘驱动器 -tile.oc.endstone.name=末地石 -tile.oc.geolyzer.name=地质分析仪 -tile.oc.hologram1.name=基础全息地图投影仪 -tile.oc.hologram2.name=高级全息地图投影仪 -tile.oc.keyboard.name=键盘 -tile.oc.microcontroller.name=单片机 -tile.oc.motionsensor.name=运动传感器 -tile.oc.netsplitter.name=网络分配器 -tile.oc.powerconverter.name=能量转换器 -tile.oc.powerdistributor.name=能量分配器 -tile.oc.print.name=3D 打印 -tile.oc.printer.name=3D 打印机 -tile.oc.raid.name=Raid磁盘阵列 -tile.oc.redstone.name=红石 I/O 端口 -tile.oc.relay.name=中继器 -tile.oc.robot.name=机器人 -tile.oc.robotafterimage.name=机器人 -tile.oc.screen1.name=基础显示屏 -tile.oc.screen2.name=高级显示屏 -tile.oc.screen3.name=超级显示屏 -tile.oc.rack.name=机架 -tile.oc.transposer.name=转运器 -tile.oc.waypoint.name=路径点 - -# Items -item.oc.abstractbuscard.name=抽象类总线卡 -item.oc.acid.name=酸液 -item.oc.alu.name=算术逻辑单元(ALU) -item.oc.analyzer.name=分析器 -item.oc.apu0.name=高级加速运算单元(APU) -item.oc.apu1.name=超级加速运算单元(APU) -item.oc.apu2.name=创造加速运算单元(APU) -item.oc.arrowkeys.name=方向键 -item.oc.buttongroup.name=按钮组 -item.oc.cardbase.name=基板 -item.oc.chamelium.name=变色材料 -item.oc.circuitboard.name=电路板 -item.oc.componentbus0.name=基础组件总线 -item.oc.componentbus1.name=高级组件总线 -item.oc.componentbus2.name=超级组件总线 -item.oc.componentbus3.name=创造模式组件总线 -item.oc.controlunit.name=控制单元(CU) -item.oc.cpu0.name=基础中央处理器(CPU) -item.oc.cpu1.name=高级中央处理器(CPU) -item.oc.cpu2.name=超级中央处理器(CPU) -item.oc.cuttingwire.name=切割线 -item.oc.datacard0.name=基础数据卡 -item.oc.datacard1.name=高级数据卡 -item.oc.datacard2.name=超级数据卡 -item.oc.debugcard.name=调试卡 -item.oc.debugger.name=网络调试器 -item.oc.diamondchip.name=钻石芯片 -item.oc.disk.name=磁碟 -item.oc.diskdrivemountable.name=可挂载软盘驱动器 -item.oc.drone.name=无人机 -item.oc.dronecase0.name=基础无人机外壳 -item.oc.dronecase1.name=高级无人机外壳 -item.oc.dronecase3.name=创造无人机外壳 -item.oc.eeprom.name=EEPROM -item.oc.floppydisk.name=软盘 -item.oc.GraphicsCard0.name=基础显卡 -item.oc.GraphicsCard1.name=高级显卡 -item.oc.GraphicsCard2.name=超级显卡 -item.oc.HardDiskDrive0.name=基础磁盘驱动器 -item.oc.HardDiskDrive1.name=高级磁盘驱动器 -item.oc.HardDiskDrive2.name=超级磁盘驱动器 -item.oc.hoverBoots.name=悬浮靴 -item.oc.inkcartridge.name=墨盒 -item.oc.inkcartridgeempty.name=空墨盒 -item.oc.internetcard.name=因特网卡 -item.oc.Interweb.name=因特网 -item.oc.ironnugget.name=铁粒 -item.oc.linkedcard.name=连接卡 -item.oc.manual.name=开放式电脑使用手册 -item.oc.memory0.name=内存条-T1 -item.oc.memory1.name=内存条-T1.5 -item.oc.memory2.name=内存条-T2 -item.oc.memory3.name=内存条-T2.5 -item.oc.memory4.name=内存条-T3 -item.oc.memory5.name=内存条-T3.5 -item.oc.microchip0.name=简易微芯片 -item.oc.microchip1.name=高级微芯片 -item.oc.microchip2.name=超级微芯片 -item.oc.microcontrollercase0.name=基础单片机外壳 -item.oc.microcontrollercase1.name=高级单片机外壳 -item.oc.microcontrollercase3.name=创造单片机外壳 -item.oc.nanomachines.name=纳米机器 -item.oc.networkcard.name=网卡 -item.oc.numpad.name=数字键盘 -item.oc.present.name=一点小礼物…… -item.oc.printedcircuitboard.name=印刷电路板(PCB) -item.oc.rawcircuitboard.name=未加工电路板 -item.oc.redstonecard0.name=基础红石卡 -item.oc.redstonecard1.name=高级红石卡 -item.oc.server0.name=基础服务器 -item.oc.server1.name=高级服务器 -item.oc.server2.name=超级服务器 -item.oc.server3.name=创造模式服务器 -item.oc.tablet.name=平板电脑 -item.oc.tabletcase0.name=基础平板电脑外壳 -item.oc.tabletcase1.name=高级平板电脑外壳 -item.oc.tabletcase3.name=创造模式平板电脑外壳 -item.oc.terminal.name=终端 -item.oc.terminalserver.name=终端服务器 -item.oc.texturepicker.name=纹理选择器 -item.oc.transistor.name=晶体管 -item.oc.upgradeangel.name=天使方块升级 -item.oc.upgradebattery0.name=基础电池升级 -item.oc.upgradebattery1.name=高级电池升级 -item.oc.upgradebattery2.name=超级电池升级 -item.oc.upgradechunkloader.name=区块载入升级 -item.oc.upgradecontainercard0.name=基础卡槽 -item.oc.upgradecontainercard1.name=高级卡槽 -item.oc.upgradecontainercard2.name=超级卡槽 -item.oc.upgradecontainerupgrade0.name=基础升级组件容器 -item.oc.upgradecontainerupgrade1.name=高级升级组件容器 -item.oc.upgradecontainerupgrade2.name=超级升级组件容器 -item.oc.upgradecrafting.name=合成升级 -item.oc.upgradedatabase0.name=基础数据库升级 -item.oc.upgradedatabase1.name=高级数据库升级 -item.oc.upgradedatabase2.name=超级数据库升级 -item.oc.upgradeexperience.name=经验升级 -item.oc.upgradegenerator.name=发电机升级 -item.oc.upgradehover0.name=基础悬浮升级 -item.oc.upgradehover1.name=高级悬浮升级 -item.oc.upgradeinventory.name=物品栏升级 -item.oc.upgradeinventorycontroller.name=物品栏控制器升级 -item.oc.upgradeleash.name=缰绳升级 -item.oc.upgrademf.name=MFU -item.oc.upgradenavigation.name=导航升级 -item.oc.upgradepiston.name=活塞升级 -item.oc.upgradesign.name=告示牌读写升级 -item.oc.upgradesolargenerator.name=太阳能发电机升级 -item.oc.upgradetank.name=水箱升级 -item.oc.upgradetankcontroller.name=储罐升级 -item.oc.upgradetractorbeam.name=牵引光束升级 -item.oc.upgradetrading.name=交易升级 -item.oc.wirelessnetworkcard0.name=基础无线网卡 -item.oc.wirelessnetworkcard1.name=高级无线网卡 -item.oc.worldsensorcard.name=世界传感器卡 -item.oc.wrench.name=螺丝刀扳手 - -# Entities -entity.oc.Drone.name=无人机 - -# GUI -oc:gui.Analyzer.Address=§6地址§f:%s -oc:gui.Analyzer.AddressCopied=地址已复制到剪贴板。 -oc:gui.Analyzer.ChargerSpeed=§6充电速度§f:%s -oc:gui.Analyzer.ComponentName=§6组件名§f:%s -oc:gui.Analyzer.Components=§6已连接组件的数量§f:%s -oc:gui.Analyzer.CopyToClipboard=点击以复制到剪贴板。 -oc:gui.Analyzer.LastError=§6上一个错误§f:%s -oc:gui.Analyzer.RobotName=§6名称§f:%s -oc:gui.Analyzer.RobotOwner=§6主人§f:%s -oc:gui.Analyzer.RobotXp=§6经验§f:%s(等级 %s) -oc:gui.Analyzer.StoredEnergy=§6存储能量§f:%s -oc:gui.Analyzer.TotalEnergy=§6存储能量上限§f:%s -oc:gui.Analyzer.Users=§6用户§f:%s -oc:gui.Analyzer.WirelessStrength=§6信号强度§f:%s -oc:gui.Assembler.Collect=收集输出 -oc:gui.Assembler.Complexity=复杂度:%s/%s -oc:gui.Assembler.InsertCase=插入一个机箱 -oc:gui.Assembler.InsertCPU=插入一个CPU -oc:gui.Assembler.InsertRAM=插入一些存储器 -oc:gui.Assembler.Progress=进度:%s%%(%s) -oc:gui.Assembler.Run=组装 -oc:gui.Assembler.Warning.BIOS=BIOS -oc:gui.Assembler.Warning.GraphicsCard=显卡 -oc:gui.Assembler.Warning.Inventory=物品栏升级 -oc:gui.Assembler.Warning.Keyboard=键盘 -oc:gui.Assembler.Warning.OS=运行环境 -oc:gui.Assembler.Warning.Screen=显示屏 -oc:gui.Assembler.Warnings=§e警告§7:推荐的组件丢失。 -oc:gui.Chat.NewVersion=有新版本可用:%s -oc:gui.Chat.TextureName=§7材质名为§a%s§f。 -oc:gui.Chat.WarningClassTransformer=执行类转换器时发生§c错误§f。请务必反馈此问题,反馈时一并附上 FML 的日志文件 §alatest.log/fml-server-latest.log§f,谢谢! -oc:gui.Chat.WarningFingerprint=§c警告§f——指纹校验不匹配!应为 '§a%s§f',实为 '§e%s§f'。如果你不是在反混淆环境下运行游戏的模组开发者,我们§l强烈§f建议你重新下载开放式电脑模组,因为你现在使用的 JAR 文件已被修改。 -oc:gui.Chat.WarningLink=无法打开链接:%s -oc:gui.Chat.WarningLuaFallback=无法使用原生 Lua 库,电脑无法持久化当前状态。它们会在区块载入时重启。 -oc:gui.Chat.WarningProjectRed=你目前使用的 Project:Red 版本不兼容 OpenComputers,请更新 Project:Red。 -oc:gui.Chat.WarningRecipes=加载合成表时遇到一个或多个错误。部分物品或因此无法合成。查阅日志文件以获取详细信息。 -oc:gui.Chat.WarningSimpleComponent=某个扩展 Mod 使用了 §aSimpleComponent§f 接口但§e做错了一些事情§f,导致组件逻辑无法注入。查阅日志文件以获取详细信息。 -oc:gui.Drive.Managed=受管理 -oc:gui.Drive.Unmanaged=不受管理 -oc:gui.Drive.ReadOnlyLock=只读锁定 -oc:gui.Drive.ReadOnlyLockWarning=§l只读§r锁定.除非抹掉该磁盘,否则无法关闭. -oc:gui.Drive.Warning=§l警告§r:切换模式将会导致当前磁盘上所有数据丢失! -oc:gui.Error.ComponentOverflow=过多的组件连接了计算机。 -oc:gui.Error.InternalError=内部错误,请检查日志文件。这可能是个Bug。 -oc:gui.Error.NoCPU=这台计算机上没有安装CPU。 -oc:gui.Error.NoEnergy=能量不足。 -oc:gui.Error.NoRAM=这台计算机上没有安装内存。 -oc:gui.Error.OutOfMemory=内存溢出。 -oc:gui.Manual.Blocks=开放式电脑-方块 -oc:gui.Manual.Home=主页 -oc:gui.Manual.Items=开放式电脑-物品 -oc:gui.Manual.Warning.BlockMissing=该方块不可用。 -oc:gui.Manual.Warning.ImageMissing=未找到图片。 -oc:gui.Manual.Warning.ItemMissing=该物品不可用。 -oc:gui.Manual.Warning.OreDictMissing=该矿物词典条目不可用。 -oc:gui.Raid.Warning=§4添加磁盘会抹掉该磁盘。[nl]移除磁盘会使Raid无法使用。 -oc:gui.Robot.Power=能量 -oc:gui.Robot.TurnOff=关闭 -oc:gui.Robot.TurnOn=开启[nl]§7使用分析器来追踪错误。§r -oc:gui.ServerRack.Back=后 -oc:gui.ServerRack.Bottom=底部 -oc:gui.ServerRack.Left=左 -oc:gui.ServerRack.None=无 -oc:gui.ServerRack.Right=右 -oc:gui.Rack.Enabled=启用 -oc:gui.Rack.Disabled=禁用 -oc:gui.ServerRack.Top=上 -oc:gui.Switch.PacketsPerCycle=数据包 / 周期 -oc:gui.Switch.QueueSize=队列长度 -oc:gui.Switch.TransferRate=传输速率 -oc:gui.Terminal.InvalidKey=无效键,看上去另一个终端已绑定到这台服务器。 -oc:gui.Terminal.OutOfRange=无信号。 - -# Containers -oc:container.adapter=适配器 -oc:container.case=计算机 -oc:container.charger=充电器 -oc:container.disassembler=分解器 -oc:container.diskdrive=磁盘驱动器 -oc:container.printer=打印机 -oc:container.raid=Raid磁盘阵列 -oc:container.relay=中继器 -oc:container.server=服务器 -oc:container.rack=机架 -oc:container.tabletwrapper=平板电脑 - -# Keybinds -key.clipboardPaste=粘贴到剪贴板 - -# Item / Block Tooltips -oc:tooltip.abstractbuscard=允许计算机向§f星门科技2§7的抽象类总线发送或接收 LIP 数据包。 -oc:tooltip.acid=一种有毒的虚构液体,通常只有某些海盗会使用它们。然而它应该有别的用途。 -oc:tooltip.adapter=用于控制非电脑组件的方块,比如原版或者来自其它模组的方块。 -oc:tooltip.alu=用来做算术及逻辑运算而不用你亲自代劳,它更能胜任这份差事。 -oc:tooltip.analyzer=用于显示方块信息,比如它们的§f地址§7和§f组件名称§7。如果计算机未能正常关闭它也会显示使计算机崩溃的报错。 -oc:tooltip.apu=如果你只是需要一个额外的卡槽,这就是你需要的自带 GPU(或者集成图形处理器 IGP)的 CPU。[nl] 支持的组件:§f%s§7[nl] 最大分辨率:§f%sx%s§7[nl] 最高色深:§f%s§7[nl] 运算/tick:§f%s§7 -oc:tooltip.assembler=允许使用若干不同的电脑组件来组装机器人。 -oc:tooltip.cable=连接方块的廉价选择。 -oc:tooltip.capacitor=储能以备不时之需。能够非常快速地充电或放电。 -oc:tooltip.carpetedcapacitor=储能以备不时之需。能够非常快速地充电或放电。有羊或豹猫踩上去的时候就能充电。 -oc:tooltip.cardbase=正如其名,它是用来安装其它扩展卡的基本卡板。 -oc:tooltip.case=计算机机箱是构建计算机的基本方块,也是各种§f扩展卡§7,§f存储器§7以及§f硬盘§7的外壳。[nl] 格子:§f%s§7 -oc:tooltip.chamelium=3D打印的基本原材料。不要误吸:或造成失明和暂时失去意识。 -oc:tooltip.chameliumblock=整洁干净的玩意。对于彩色 3D 打印相当实用,或者只是拿它的整洁干净的色彩来装饰你的华丽的基地。 -oc:tooltip.charger=将电容器的能量传输给相邻机器人。传输效率取决于输入的§f红石信号§7强度,无信号意味着不给机器人充电,而最强信号则意味着全速给机器人充电。 -oc:tooltip.circuitboard=现在我们已经取得一些进展。可以通过蚀刻来得到印制电路板。 -oc:tooltip.controlunit=用来控制……控制东西……的单元。你需要这玩意儿来做 CPU。所以反正啦,这个非常重要。 -oc:tooltip.componentbus=这个扩展能让服务器同时与更多组件通讯,工作原理类似 CPU。[nl] 支持的组件:§f%s§7 -oc:tooltip.cpu=所有计算机最核心的组件,它的时钟频率有点不可靠,但是你考虑到它是靠便携日晷来运行的,还能指望什么呢?[nl] 支持组件:§f%s§7 -oc:tooltip.cpu.Architecture=架构:§f%s§7 -oc:tooltip.cuttingwire=用于将粘土块切割成电路板的形状。使用一次就会坏掉,这可能使得成为历来最低效的工具。 -oc:tooltip.datacard0=提供数种高级算法,例如散列、压缩和解压缩算法。 -oc:tooltip.datacard1=提供数种高级算法,例如散列、AES 加密、压缩和解压缩算法。 -oc:tooltip.datacard2=提供数种高级算法,例如散列、AES 加密、椭圆曲线加密、压缩和解压缩算法。 -oc:tooltip.debugcard=创造模式物品,它能让你更简易的操控世界来进行测试。请自己承担它带来的危险。 -oc:tooltip.debugger=用于在 OpenComputer 的内部网络格栅中输出调试信息。请在开发者指导下使用。 -oc:tooltip.diamondchip=一小粒正在发光的钻石。永远不会破镜重圆。 -oc:tooltip.disassembler=将物品分解成基础组件。§l警告§7:分解得到的物品会有 %s%% 的几率在分解过程中损坏! -oc:tooltip.disk=用于制造持久存储设备的原始媒介材料。 -oc:tooltip.diskdrive.CC=§a支持§7 ComputerCraft 的软盘。 -oc:tooltip.diskdrive=用来读写软盘。可以给机器人安装使其可以插入软盘。 -oc:tooltip.diskdrivemountable=和普通软驱用途一样,但必须装载在机架里。 -oc:tooltip.diskusage=磁盘使用:%s/%s 字节 -oc:tooltip.diskmodemanaged=模式:管理 -oc:tooltip.diskmodeunmanaged=模式:不受管理 -oc:tooltip.drone=无人机是一种轻量而快速的侦查单位,自身拥有有限的载物空间。 -oc:tooltip.dronecase=这个外壳将会在组装机中组装出无人机。这个外壳可容纳少量组件,并内建末地石驱动的悬浮系统。 -oc:tooltip.eeporm=小型的可编程存储器,可存储电脑启动所用的BIOS。 -oc:tooltip.fakeendstone=几乎可以以假乱真,甚至更加轻盈! -oc:tooltip.geolyzer=可以检测周围方块的硬度。这些信息对编写全息地图程序或检测矿物都有很大的帮助。 -oc:tooltip.graphicscard=用来改变屏幕上的显示内容。最高分辨率:§f%sx%s§7[nl] 最高色深:§f%s§7[nl] 运算/tick:§f%s§7 -oc:tooltip.hoverboots=跳得更高,摔得更深,走得更快。一切尽在 Hover Boots™,已获顶级认证。 -oc:tooltip.inkcartridge=用于重新填装3D打印机的墨水。因为某些原因这些墨水不必保留在打印机里。 -oc:tooltip.inkcartridgeempty=此墨盒经过深度干燥处理。用颜料重新装填,抑或弃置。看我脸色行事。 -oc:tooltip.internetcard=因特网卡可以让你发送HTTP请求以及使用货真价实的TCP套接字。 -oc:tooltip.interweb=恭喜,你赢得了一个因特网。你可以使用因特网卡来连接它。注意:不要水贴钓鱼 -oc:tooltip.ironnugget=颗粒状的铁,所以叫铁粒啦,蠢蠢的感觉…… -oc:tooltip.keyboard=可以连接屏幕来输入显示文本。 -oc:tooltip.hologram0=一个能通过电脑控制来投射出任何三维结构的全息投影仪.[nl] 分辨率:§f48x32x48§7 [nl] 最大显示规模:§f3x§7 [nl] 最高色深:§f黑白§7 -oc:tooltip.hologram1=使用电脑控制的高级全息投影仪。[nl] 分辨率:§f48x32x48§7 [nl] 最大显示规模:§f4x§7 [nl] 最高色深:§f三原色§7 -oc:tooltip.linkedcard=连接卡可以成对合成,并且它们只能与各自对应的连接卡交互。然而,它们之间的交互没有距离限制,甚至可以跨越不同的世界。但它们传递信息所需要的能量消耗不多不少。 -oc:tooltip.linkedcard_channel=§8频道:%s§7 -oc:tooltip.manual=包含你需要的关于 OpenComputer 的一切信息。还有更多。为此你只需要……§o请按R键继续§7。 -oc:tooltip.memory=电脑运行必备。内存越大,你就可以运行越复杂的程序。 -oc:tooltip.microchip=通常也管这种芯片叫集成电路。我也不知道为什么能和红石一起运行,但事实如此。 -oc:tooltip.microcontroller=单片机是被压缩到不能再压缩的电脑。它们更多是用于执行特殊任务,并只运行一个内建于EEPROM中的简单程序。[nl] §c不能和外置组件相连接。§7 -oc:tooltip.microcontrollercase=单片机基础组件。在组装机中为其添加各种组件并组装单片机。 -oc:tooltip.motionsensor=可以检测附近生物的动向。检测需要无遮挡物的环境。 -oc:tooltip.nanomachines=控制单元,同时还是一堆可以吸入的纳米机器(如果你愿意的话)。 -oc:tooltip.networkcard=允许通过其他方块(比如线缆)相连的远程计算机能够向彼此发送信息进行交互。 -oc:tooltip.poweracceptor=能量转换速度:§f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§fMJ§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§fCharge§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§fEU§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§fJoules§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§fRF§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§fCoulombs§7: §a%s:%s§7 -oc:tooltip.powerconverter=将其它模组的能量转化为本模组的内部能源形式。转换比: -oc:tooltip.powerdistributor=在不同网络中分配能量。很实用于通过包含多个理论上独立子网络的转换器在系统中共享能量。 -oc:tooltip.present=……它随时为你的麻烦待命。打开此礼物将有机会获得 §kphat lewt§7![nl]§8在时机合适时,合成 OpenComputers 的物品。§7 -oc:tooltip.print.BeaconBase=§8可用作信标底座。 -oc:tooltip.print.LightValue=§8光强:%s。 -oc:tooltip.print.RedstoneLevel=§8红石信号强度:%s。 -oc:tooltip.printedcircuitboard=扩展卡、内存等组件的基础板。 -oc:tooltip.printer=利用变色物质和墨盒打印出用户自定义的形状。需要用电脑进行配置。不要让幼童接触。就是这样。 -oc:tooltip.raid=允许将三块硬盘组成一个大文件系统供所有与其连接的电脑使用。 -oc:tooltip.rawcircuitboard=能在支持原版熔炉配方的炉子中加工强化。 -oc:tooltip.redstone=能够在方块周围接收或发送红石信号。可以被与之相连的计算机控制。基本上就像一个外置红石卡。 -oc:tooltip.redstonecard.Charset=§a兼容§7 §fSimpleLogic§7。 -oc:tooltip.redstonecard.ProjectRed=§a兼容§7 §fProject Red§7。 -oc:tooltip.redstonecard.RedLogic=§a兼容§7 §fRedLogic§7。 -oc:tooltip.redstonecard.RedNet=§a兼容§7 §fRedNet§7。 -oc:tooltip.redstonecard.WirelessCBE=§a兼容§7 §f无线红石(ChickenBones)§7。 -oc:tooltip.redstonecard.WirelessSV=§a兼容§7 §f无线红石(SlimeVoid)§7。 -oc:tooltip.redstonecard=允许在计算机和机器人四周接收或发送红石信号。 -oc:tooltip.relay=可将不同网络连接在一起。仅信息可通过此设备传递,其它元件仍不可见。用法举例:可用于保持多个独立网络的通信。 -oc:tooltip.robot=和计算机不同,机器人能够移动并且像玩家那样与世界中的东西交互。然而,它们§o不能§r§7直接与外设进行交互! -# The underscore makes sure this isn't hidden with the rest of the tooltip。 -oc:tooltip.robot_level=§f等级§7:§a%s§7。 -oc:tooltip.robot_storedenergy=§f存储能量§7:§a%s§7。 -oc:tooltip.screen=显示文本,运作需要机箱中的显卡。[nl] 最高分辨率:§f%sx%s§7[nl] 最高色深:§f%s§7 -oc:tooltip.server=这就是服务器,它与许多其它的服务器拥有相似功能,但这台服务器可以使用组件进行升级,就像升级机箱一样。它也可以放入服务器机架中运行。 -oc:tooltip.server.Components=已安装的组件: -oc:tooltip.rack=它能装下四台服务器或者别的设备。 -oc:tooltip.tablet=一台平板电脑,为 Lua 新人准备。潜行时右击可强制关机。 -oc:tooltip.tabletcase=平板电脑的基础外壳。在组装机中添加组件以制造平板电脑。 -oc:tooltip.terminal=可以远程控制服务器,不过前提是你处于信号范围内。使用方法相同于显示屏与键盘. Shift 右击机架中的服务器可以绑定对应的终端。 -oc:tooltip.terminalserver=在工作范围内可与终端连接,以提供远程控制功能。内建有虚拟显示器和键盘。 -oc:tooltip.texturepicker=这个工具可以显示放块表面的描述,可用于3D打印定义中。完全不是材质名,完全不是。很抱歉先生,不是。 -oc:tooltip.tier=§8等级 %s -oc:tooltip.netsplitter=作为动态连接器的存在。每个面的连接设定可通过扳手切换。红石信号可反相所有面的连接设定。 -oc:tooltip.toolong=按住 [§f%s§7] 显示详细物品信息。 -oc:tooltip.transistor=大多数电脑组件中最基础的元素。看上去有些扭曲,但它是有用的。 -oc:tooltip.transposer=可在相邻容器之间自动转移物品和液体。 -oc:tooltip.upgradeangel=允许机器人凭空放置方块,甚至是在没有任何依附的情况下。 -oc:tooltip.upgradebattery=增加机器人存储能量的上限,让其能够运作很长一段时间也不必充电。[nl] 电容:§f%s§7 -oc:tooltip.upgradechunkloader=如果机器人走进了一片森林,周围没有任何生物载入区块,那么它还能继续移动吗? 这个升级组件可以让你确定这点。它能让机器人所处的区块保持载入,但这会让能量不断地消耗。 -oc:tooltip.upgradecontainercard=卡容器组件可以让你方便随意的将卡装入机器人或从中移出。[nl] 最高等级:§f%s§7 -oc:tooltip.upgradecontainerupgrade=卡容器升级组件可以让你方便的将卡装入另一个卡容器或从中移出。[nl] 最高等级:§f%s§7 -oc:tooltip.upgradecrafting=能让机器人的物品栏左上角部分成为合成界面。物品必须在合成界面里排列整齐。 -oc:tooltip.upgradedatabase=能对物品信息进行分类,供其它组件稍后取用。[nl] 可支持条目数量:§f%s§7 -oc:tooltip.upgradeexperience=这个升级能让机器人在执行一些工作时获取经验并累积。它们拥有越多的累积经验,就能够存储越多的能量,越快的挖掘方块并且使用工具时拥有更高的效率。 -oc:tooltip.upgradegenerator=可以让机器人通过燃料充能。燃烧物品得到的发电量取决于燃料的等级。[nl] §f发电效率§7:§a%s%%§7 -oc:tooltip.upgradehover=这个升级组件可让机器人飞得更高而无需爬墙。[nl] 最大高度:§f%s§7 -oc:tooltip.upgradeinventory=这个升级组件为机器人提供了物品背包。如果没有这个升级,机器人将不能存储物品。 -oc:tooltip.upgradeinventorycontroller=这个升级组件可以控制机器人使其与外部容器互动,并能允许机器人将装备上的工具替换成其物品栏中的其它物品。 -oc:tooltip.upgrademf=能让适配器访问不与其相邻的方块。 -oc:tooltip.upgrademf.Linked=§f已连接§7 -oc:tooltip.upgrademf.Unlinked=§f没有连接§7 -oc:tooltip.upgradeleash=这个升级组件可让诸如无人机之类的设备绑在 Isaa——不好意思,*清清嗓子* 我刚才说错了。我只是被告知这原本是用来拴动物的绳子。可以拴很多动物,好奇怪啊。 -oc:tooltip.upgradenavigation=可以让机器人确认所处位置以及定位。定位地点即为用于合成此升级组件用到的地图的中心点。 -oc:tooltip.upgradepiston=这个升级十分有用。它能让机器人像活塞那样移动方块,但 §l不能§7 移动实体。 -oc:tooltip.upgradesign=允许机器人读写告示牌。 -oc:tooltip.upgradesolargenerator=可以让机器人在太阳光的照射下四处奔走。机器人顶部需要无任何方块阻挡。产能速度是斯特林引擎的 %s%%。 -oc:tooltip.upgradetank=为你的机器人装上一个可存储流体的水箱。如果没有升级此功能,你的机器人将无法在内部存储流体。 -oc:tooltip.upgradetankcontroller=这个升级能让你的机器人与外界水箱交互,向其传输流体。 -oc:tooltip.upgradetractorbeam=十分先进的高科技,别名“物品磁铁”。它能让机器人在任何地方捡起3格范围内的掉落物。 -oc:tooltip.waypoint=为安装有导航升级的设备提供参考点。 -oc:tooltip.wirelessnetworkcard=允许在发送正常信息的情况下发送无线网络信息。请确保已设置好 §f信号强度§7 否则不会发出信息。越高的信号强度会导致越高的能量消耗。 -oc:tooltip.worldsensorcard=可读取关于世界的各种信息,例如重力加速度和是否有可供呼吸的大气。使用风险自负。制造商对由卡片输出结果造成的损失不承担任何法律责任。我们不仅有律师,还有现金。不要试图告倒我们。 -oc:tooltip.wrench=螺丝刀和扳手混合体,新手友好,高手毁灭者。 - -#Achievements -achievement.oc.adapter=Plug In Baby -achievement.oc.adapter.desc=和其它 MOD 的方块(甚至是原版 Minecraft 方块)进行互动! -achievement.oc.assembler=完美 -achievement.oc.assembler.desc=是时候征服世界了! -achievement.oc.cable=并不是脏兮兮的电线 -achievement.oc.cable.desc=搭配权威认证的反 SCP-229 科技 -achievement.oc.capacitor=本设备含电池 -achievement.oc.capacitor.desc=不可能阻止它 -achievement.oc.card=我们接受卡片 -achievement.oc.card.desc=这是为方便您的使用。我们保证这不是别有用心。 -achievement.oc.case=以备后患 -achievement.oc.case.desc=Because cuboid towers are the best. -achievement.oc.charger=那就开始做吧! -achievement.oc.charger.desc=开始充——等等!又忘记红石信号了。 -achievement.oc.chip=全是些小东西 -achievement.oc.chip.desc=曾经真空管也是这样的。 -achievement.oc.cpu=超频 -achievement.oc.cpu.desc=是时候好好利用这些计算循环了 -achievement.oc.disassembler=销毁! -achievement.oc.disassembler.desc=当你发现你的想法很美好,但现实其实很残酷的时候,就用这个吧。 -achievement.oc.diskDrive=Roundabout -achievement.oc.diskDrive.desc=Inferior capacity but such delicious sound. -achievement.oc.drone=啊!飞走了! -achievement.oc.drone.desc=冷静冷静,直接用核弹让他们在轨道上瞬间爆炸 -achievement.oc.eeprom=每台电脑 -achievement.oc.eeprom.desc=仅限一个,就是这样。这是用来决定最终启动顺序的,明白吗!? -achievement.oc.floppy=The One Ri- Disk -achievement.oc.floppy.desc=不要与flappy混淆。[nl]注:软盘英文为floppy disk -achievement.oc.geolyzer=深入地心 -achievement.oc.geolyzer.desc=It has extraordinary qualities. -achievement.oc.graphicsCard=LastGen -achievement.oc.graphicsCard.desc=The way it's meant to be... uh... rendered. Yeah. That. -achievement.oc.hdd=Hot Dog Dealer(热狗推销员) -achievement.oc.hdd.desc=等等我不是那个意思。让我想想,好像想起来什么意思了…… -achievement.oc.hologram=下一个次元 -achievement.oc.hologram.desc=因为 2D 很无聊啊。或者本来就这样? -achievement.oc.keyboard=吸尘器 3000 型 -achievement.oc.keyboard.desc=强烈建议使用时保持将其翻过来并持续摇晃的习惯,以清理其中异物。 -achievement.oc.microcontroller=Little Sisters -achievement.oc.microcontroller.desc=计算机的小妹妹哦 -achievement.oc.motionSensor=Got the Moves -achievement.oc.motionSensor.desc=Like Steve Swagger. -achievement.oc.networkCard=现在我们在聊天了! -achievement.oc.networkCard.desc=Keep in touch with those distant relatives via transitive relations. -achievement.oc.openOS=启动 -achievement.oc.openOS.desc=One OS to - wait, I used that one already? Dang. -achievement.oc.powerDistributor=分享即关怀 -achievement.oc.powerDistributor.desc=当你在平衡供电时需要帮助的时候。 -achievement.oc.rack=Dat Rack -achievement.oc.rack.desc=我不知道你想歪到哪里去了,我已经说得很明白了,就是服务器架。 -achievement.oc.raid=LFG -achievement.oc.raid.desc=Heroic plzkthx. -achievement.oc.ram=随机存取存储器 -achievement.oc.ram.desc=恭喜,你的操作完全正确。 -achievement.oc.redstoneCard=联系 -achievement.oc.redstoneCard.desc=模拟信号时间到。 -achievement.oc.redstoneIO=The Outsider -achievement.oc.redstoneIO.desc=将红石信号传播到你需要的地方! -achievement.oc.robot=Beep Boop -achievement.oc.robot.desc=灭绝! -achievement.oc.screen=试过反复开关这屏幕没? -achievement.oc.screen.desc=真没有。毕竟红石信号就可以开关这屏幕了。 -achievement.oc.server=专用 -achievement.oc.server.desc=云服务,现已正式推出。 -achievement.oc.switch=复杂拓扑学 -achievement.oc.switch.desc=远离易碎货物,因为包裹可能会掉下来。 -achievement.oc.tablet=不要吸入 -achievement.oc.tablet.desc=同时请远离儿童,以避免不必要的信用卡过度透支。 -achievement.oc.transistor=Tell Red I said "Hi." -achievement.oc.transistor.desc=制作一个晶体管然后让它工作。然后听录音带。不用谢我。 -achievement.oc.wirelessNetworkCard=信号 -achievement.oc.wirelessNetworkCard.desc=是时候让数据包踏遍每一个角落了。 - -# Death messages. Note that the number of entries here must match the number -# set in the actual damage source in code。 -death.attack.oc.nanomachinesOverload.1=%s 过于贪婪。 -death.attack.oc.nanomachinesOverload.2=%s 神经断裂。 -death.attack.oc.nanomachinesOverload.3=%s 的纳米机器失控暴走了。 -death.attack.oc.nanomachinesHungry.1=%s 被纳米机器吃掉了。 -death.attack.oc.nanomachinesHungry.2=%s 忘记喂饱纳米机器了。 -death.attack.oc.nanomachinesHungry.3=%s 已被分解吸收了。 - -# NEI Integration -nei.options.inventory.oredict=显示矿物词典名 -nei.options.inventory.oredict.true=是 -nei.options.inventory.oredict.false=否 -nei.usage.oc.Manual=打开手册 - -# Waila Integration -option.oc.address=地址 -option.oc.componentName=组件名 -option.oc.energy=能量 diff --git a/src/main/resources/assets/opencomputers/lang/zh_TW.lang b/src/main/resources/assets/opencomputers/lang/zh_TW.lang deleted file mode 100644 index 0f7717bab8..0000000000 --- a/src/main/resources/assets/opencomputers/lang/zh_TW.lang +++ /dev/null @@ -1,468 +0,0 @@ -# OpenComputer -# This is the Traditional Chinese file for localizations. by mymag - -# Blocks -tile.oc.accesspoint.name=§c橋接器§7 -tile.oc.adapter.name=連接器 -tile.oc.assembler.name=機器組裝台 -tile.oc.cable.name=線纜 -tile.oc.capacitor.name=電容 -tile.oc.case1.name=基礎電腦機殼 -tile.oc.case2.name=高級電腦機殼 -tile.oc.case3.name=超級電腦機殼 -tile.oc.casecreative.name=電腦機殼(創造模式) -tile.oc.chameliumblock.name=變色凝膠磚 -tile.oc.charger.name=充電器 -tile.oc.disassembler.name=拆解機 -tile.oc.diskdrive.name=磁碟機 -tile.oc.endstone.name=終界石 -tile.oc.geolyzer.name=硬度分析機 -tile.oc.hologram1.name=全息投影機 (1級) -tile.oc.hologram2.name=全息投影機 (2級) -tile.oc.keyboard.name=鍵盤 -tile.oc.microcontroller.name=微型控制器 -tile.oc.motionsensor.name=動作感應器 -tile.oc.netsplitter.name=網路路由器 -tile.oc.powerconverter.name=能源轉換器 -tile.oc.powerdistributor.name=能源分配器 -tile.oc.print.name=3D 列印 -tile.oc.printer.name=3D 列印機 -tile.oc.raid.name=磁碟陣列機(NAS) -tile.oc.redstone.name=紅石I/O -tile.oc.relay.name=中繼器 -tile.oc.robot.name=機器人 -tile.oc.robotafterimage.name=機器人 -tile.oc.screen1.name=黑白電腦顯示器 -tile.oc.screen2.name=彩色電腦顯示器 -tile.oc.screen3.name=高畫質電腦顯示器 -tile.oc.rack.name=伺服器機架 -tile.oc.switch.name=路由器 -tile.oc.transposer.name=差轉機 -tile.oc.waypoint.name=路點 - -# Items -item.oc.abstractbusCard.name=抽象的介面卡 -item.oc.acid.name=蝕刻藥水 -item.oc.alu.name=算邏運算單元(ALU) -item.oc.analyzer.name=分析器 -item.oc.apu0.name=加速處理單元 (APU) (1級) -item.oc.apu1.name=加速處理單元 (APU) (2級) -item.oc.apu2.name=加速處理單元 (APU) (創造模式) -item.oc.arrowkeys.name=方向鍵 -item.oc.buttongroup.name=按鈕組 -item.oc.cardbase.name=主板 -item.oc.chamelium.name=變色凝膠 -item.oc.circuitboard.name=電路板 -item.oc.componentbus0.name=基礎排線 -item.oc.componentbus1.name=高級排線 -item.oc.componentbus2.name=超級排線 -item.oc.controlunit.name=控制單元 (CU) -item.oc.cpu0.name=中央處理器 (CPU) (1級) -item.oc.cpu1.name=中央處理器 (CPU) (2級) -item.oc.cpu2.name=中央處理器 (CPU) (3級) -item.oc.cuttingwire.name=切割線 -item.oc.datacard0.name=資料卡 (1級) -item.oc.datacard1.name=資料卡 (2級) -item.oc.datacard2.name=資料卡 (3級) -item.oc.debugcard.name=除錯卡 -item.oc.debugger.name=網路除錯卡 -item.oc.disk.name=磁碟 -item.oc.drone.name=無人機 -item.oc.dronecase0.name=無人機外殼 (1級) -item.oc.dronecase1.name=無人機外殼 (2級) -item.oc.dronecase3.name=無人機外殼 (創造模式) -item.oc.eeprom.name=電子抹除式可複寫唯讀記憶體(EEPROM) -item.oc.floppydisk.name=磁碟片 -item.oc.graphicscard0.name=顯示卡 -item.oc.graphicscard1.name=彩色顯示卡 -item.oc.graphicscard2.name=高畫質顯示卡 -item.oc.harddiskdrive0.name=硬碟機 (1級) -item.oc.harddiskdrive1.name=硬碟機 (2級) -item.oc.harddiskdrive2.name=硬碟機 (3級) -item.oc.hoverboots.name=懸停靴 -item.oc.inkcartridge.name=墨水匣 -item.oc.inkcartridgeempty.name=墨水匣(空) -item.oc.internetcard.name=上網卡 -item.oc.interweb.name=因特網 -item.oc.ironnugget.name=鐵粒 -item.oc.linkedcard.name=連結卡 -item.oc.manual.name=開放式電腦手冊 -item.oc.memory0.name=記憶卡 (1級) -item.oc.memory1.name=記憶卡 (1.5級) -item.oc.memory2.name=記憶卡 (2級) -item.oc.memory3.name=記憶卡 (2.5級) -item.oc.memory4.name=記憶卡 (3級) -item.oc.memory5.name=記憶卡 (3.5級) -item.oc.microchip0.name=微晶片 (1級) -item.oc.microchip1.name=微晶片 (2級) -item.oc.microchip2.name=微晶片 (3級) -item.oc.microcontrollercase0.name=微控制器外殼 (Tier 1) -item.oc.microcontrollercase1.name=微控制器外殼 (Tier 2) -item.oc.microcontrollercase3.name=微控制器外殼 (Creative) -item.oc.nanomachines.name=納米機器 -item.oc.networkcard.name=網路卡 -item.oc.numpad.name=數字鍵盤 -item.oc.present.name=一個小東西... -item.oc.printedcircuitboard.name=印刷電路板(PCB) -item.oc.rawcircuitboard.name=電路板材料 -item.oc.redstonecard0.name=紅石卡 (1級) -item.oc.redstonecard1.name=紅石卡 (2級) -item.oc.server0.name=伺服器 (1級) -item.oc.server1.name=伺服器 (2級) -item.oc.server2.name=伺服器 (3級) -item.oc.server3.name=伺服器 (創造模式) -item.oc.tablet.name=平板電腦 -item.oc.tabletcase0.name=平板電腦保護套 (1級) -item.oc.tabletcase1.name=平板電腦保護套 (2級) -item.oc.tabletcase3.name=平板電腦保護套 (創造模式) -item.oc.terminal.name=遠端終端機 -item.oc.texturepicker.name=紋理選擇器 -item.oc.transistor.name=電晶體 -item.oc.upgradeangel.name=天使升級 -item.oc.upgradebattery0.name=電池升級 (1級) -item.oc.upgradebattery1.name=電池升級 (2級) -item.oc.upgradebattery2.name=電池升級 (3級) -item.oc.upgradechunkloader.name=區塊載入器升級 -item.oc.upgradecontainercard0.name=卡片集裝箱 (1級) -item.oc.upgradecontainercard1.name=卡片集裝箱 (2級) -item.oc.upgradecontainercard2.name=卡片集裝箱 (3級) -item.oc.upgradecontainerupgrade0.name=集裝箱升級 (1級) -item.oc.upgradecontainerupgrade1.name=集裝箱升級 (2級) -item.oc.upgradecontainerupgrade2.name=集裝箱升級 (3級) -item.oc.upgradecrafting.name=合成升級 -item.oc.upgradedatabase0.name=資料庫升級 (1級) -item.oc.upgradedatabase1.name=資料庫升級 (2級) -item.oc.upgradedatabase2.name=資料庫升級 (3級) -item.oc.upgradeexperience.name=經驗升級 -item.oc.upgradegenerator.name=發電機升級 -item.oc.upgradehover0.name=懸停升級 (1級) -item.oc.upgradehover1.name=懸停升級 (2級) -item.oc.upgradeinventory.name=物品欄升級 -item.oc.upgradeinventorycontroller.name=物品控制器升級 -item.oc.upgradeleash.name=皮帶升級 -item.oc.upgradenavigation.name=導航升級 -item.oc.upgradepiston.name=活塞升級 -item.oc.upgradesign.name=告示牌 I/O 升級 -item.oc.upgradesolargenerator.name=太陽能發電升級 -item.oc.upgradetank.name=水箱升級 -item.oc.upgradetankcontroller.name=高級水箱升級 -item.oc.upgradetractorbeam.name=牽引光束升級 -item.oc.wirelessnetworkcard0.name=無線網卡 -item.oc.wirelessnetworkcard1.name=無線網卡 -item.oc.worldsensorcard.name=世界傳感器卡 -item.oc.wrench.name=螺絲刀扳手 - -# Entities -entity.oc.drone.name=無人機 - -# GUI -oc:gui.Analyzer.Address=§6位址§f: %s -oc:gui.Analyzer.AddressCopied=位址複製到剪貼簿. -oc:gui.Analyzer.ChargerSpeed=§6充電速度§f: %s -oc:gui.Analyzer.ComponentName=§6設備元件名稱§f: %s -oc:gui.Analyzer.Components=§6連接元件的數量§f: %s -oc:gui.Analyzer.CopyToClipboard=點擊複製到剪貼簿。 -oc:gui.Analyzer.LastError=§6上一個錯誤§f: %s -oc:gui.Analyzer.RobotName=§6名字§f: %s -oc:gui.Analyzer.RobotOwner=§6持有者§f: %s -oc:gui.Analyzer.RobotXp=§6經驗值§f: %s -oc:gui.Analyzer.StoredEnergy=§6儲存能量§f: %s -oc:gui.Analyzer.TotalEnergy=§6總儲存能量§f: %s -oc:gui.Analyzer.Users=§6使用者§f: %s -oc:gui.Analyzer.WirelessStrength=§6信號強度§f: %s -oc:gui.Assembler.Collect=收集機器人 -oc:gui.Assembler.Complexity=複雜性: %s/%s -oc:gui.Assembler.InsertCase=裝入電腦機殼(CASE) -oc:gui.Assembler.InsertCPU=裝入中央處理器(CPU) -oc:gui.Assembler.InsertRAM=裝入一些記憶體(RAM) -oc:gui.Assembler.Progress=進度: %s%% (%s) -oc:gui.Assembler.Run=開始組裝機器人 -oc:gui.Assembler.Warnings=§e警告§7: 缺少某些建議的零組件 -oc:gui.Assembler.Warning.GraphicsCard=顯示卡 -oc:gui.Assembler.Warning.Inventory=物品欄升級組件 -oc:gui.Assembler.Warning.Keyboard=鍵盤 -oc:gui.Assembler.Warning.OS=開機(作業系統) 中等 -oc:gui.Assembler.Warning.Screen=螢幕 -oc:gui.Assembler.Warnings=§e警告§7: 缺少建議的零組件 -oc:gui.Chat.NewVersion=有新版本可用: %s -oc:gui.Chat.TextureName=§7紋理名稱是 §a%s§f. -oc:gui.Chat.WarningClassTransformer=There were §cerrors§f running the class transformer. Please report this, together with your (full!) FML §alatest.log§f/§afml-server-latest.log§f logfile, thank you! -oc:gui.Chat.WarningFingerprint=§c警告§f - 指紋不符!預期 '§a%s§f' 但得到 '§e%s§f'. Unless you are a modder and are running the deobfuscated version of the mod, it is §lstrongly§f recommended to redownload OpenComputers, because the JAR you are using may have been tampered with. -oc:gui.Chat.WarningLink=無法打開鏈接: %s -oc:gui.Chat.WarningLuaFallback=本機 LUA 函式庫無法使用,電腦將無法維持狀態,他會重新啟動並且載入區塊 -oc:gui.Chat.WarningProjectRed=你正在使用的 Project: Red 模組與 OpenComputers 不相容. 請嘗試更新 Project: Red. -oc:gui.Chat.WarningRecipes=There were errors loading one or more recipes. Some items may be uncraftable. Please check your log file for more information. -oc:gui.Chat.WarningSimpleComponent=An addon (yours?) using the §aSimpleComponent§f interface did §esomething wrong§f. Component logic could not be injected. Please check your log file for more information. -oc:gui.Drive.Managed=受管 -oc:gui.Drive.Unmanaged=非受管 -oc:gui.Drive.Warning=§l警告§r: 切換模式會導致目前儲存在硬碟上的所有資料遺失! -oc:gui.Error.ComponentOverflow=太多的元件連接到電腦上了 -oc:gui.Error.InternalError=內部錯誤,請查看日誌文件。這可能是一個錯誤。 -oc:gui.Error.NoCPU=電腦內沒有安裝中央處理器(CPU). -oc:gui.Error.NoEnergy=沒有能源 -oc:gui.Error.NoRAM=電腦內沒有安裝記憶卡 -oc:gui.Error.OutOfMemory=記憶體不足 -oc:gui.Manual.Blocks=開放式電腦方塊 -oc:gui.Manual.Home=首頁 -oc:gui.Manual.Items=開放式電腦物品 -oc:gui.Manual.Warning.BlockMissing=方塊不存在 -oc:gui.Manual.Warning.ImageMissing=沒有找到圖片 -oc:gui.Manual.Warning.ItemMissing=物品不存在 -oc:gui.Manual.Warning.OreDictMissing=礦物字典不存在 -oc:gui.Raid.Warning=§4放入的硬碟機會清除硬碟資料.[nl] 移除硬碟機會刪除磁碟陣列機(NAS)資料. -oc:gui.Robot.Power=能量 -oc:gui.Robot.TurnOff=關閉 -oc:gui.Robot.TurnOn=開啟 -oc:gui.Rack.None=無 -oc:gui.Rack.Back=背面 -oc:gui.Rack.Bottom=底部 -oc:gui.Rack.Left=左 -oc:gui.Rack.Right=右 -oc:gui.Rack.Top=上 -oc:gui.Switch.TransferRate=週期率 -oc:gui.Switch.PacketsPerCycle=封包 / 週期 -oc:gui.Switch.QueueSize=隊列大小 -oc:gui.Terminal.InvalidKey=按鍵無效時,最有可能另一端已經綁定到伺服器。 -oc:gui.Terminal.OutOfRange=沒訊號. - -# Containers -oc:container.accesspoint=橋接器 -oc:container.adapter=連接器 -oc:container.case=電腦 -oc:container.charger=充電器 -oc:container.disassembler=拆解機 -oc:container.diskdrive=硬碟機 -oc:container.printer=印表機 -oc:container.raid=磁碟陣列機(NAS) -oc:container.relay=中繼器 -oc:container.server=伺服器 -oc:container.rack=伺服器機架 -oc:container.switch=路由器 -oc:container.tabletwrapper=平板電腦 - -# Keybinds -key.clipboardPaste=貼上剪貼簿 -key.materialCosts=顯示材料成本 - -# Item / Block Tooltips -oc:tooltip.accesspoint=就像一個切換器,但它會接收無線封包並且轉換無線的封包變成有線的封包. -oc:tooltip.abstractbuscard=允許與 §fStargateTech 2§7 抽象卡傳送與接收 LIP 封包. -oc:tooltip.acid=一種有毒的假液相物質,通常只有某些海盜會使用它們.[nl]它的腐蝕特性令它非常完美地適用于蝕刻電路板的材料. -oc:tooltip.adapter=用于控制非電腦組件的方塊,[nl]比如原版或者來自其他模組的方塊. -oc:tooltip.alu=用來做算邏運算以免你親自代勞,[nl]它更勝任這份差事. -oc:tooltip.analyzer=用于顯示方塊信息,比如它們的§f地址§7和§f組件名稱§7.[nl]如果計算機未能正常關閉它也會顯示使得計算機崩潰的報錯. -oc:tooltip.apu=這是 CPU 組成 GPU (或 IGP)的一個處理器, 如果你需要額外的卡片插槽,他可以讓你減少一片顯示卡.[nl] 支援的零組件: §f%s§7[nl] 最大分辨率: §f%sx%s§7[nl] 最大顏色深度: §f%s§7[nl] 運作/tick: §f%s§7 -oc:tooltip.assembler=機器組裝台可以從不同的電腦零組件來組裝一台機器人。 -oc:tooltip.cable=連接方塊的廉價選擇. -oc:tooltip.capacitor=儲能以備他用.[nl]能夠非常快速地充電放電. -oc:tooltip.cardbase=正如其名,它是用來安裝其他擴展卡的基本卡板. -oc:tooltip.case=計算機電腦機殼是構建計算機的基本方塊,[nl]也是各種§f介面卡§7,§f記憶體§7以及§f硬碟§7的外殼.[nl] 格子: §f%s§7 -oc:tooltip.chamelium=3D列印的原料. 不可吞食: 會導致失明與臨時性身體消失 -oc:tooltip.chameliumblock=乾淨清潔. 方便用於3D列印, 只是一個純色的乾淨方塊, 彩色方塊可以讓你發揮創意 -oc:tooltip.charger=將電容器的能量傳輸給相鄰機器人.[nl]傳輸效率取決于輸入的§f紅石信號§7強度,無信號意味著不給機器人充電,而最強信號則意味著全速給機器人充電. -oc:tooltip.circuitboard=現在我們已經取得一些進展.[nl]可以通過蝕刻來得到印制板. -oc:tooltip.controlunit=用來控制...控制東西...的單元.[nl]你需要這玩意兒來做CPU.所以反正啦,這個非常重要. -oc:tooltip.componentbus=這個擴充套件能讓伺服器同時與更多組件通訊, 工作原理類似CPU.[nl] 支援的組件: §f%s§7. -oc:tooltip.cpu=所有計算機最核心的組件,它的時鐘頻率有點不可靠,[nl]但是你考慮到它是靠便攜日晷來運行的你還能指望啥呢? -oc:tooltip.cpu.architecture=架構: §f%s§7 -oc:tooltip.cuttingwire=用于將粘土塊切割成電路板的形狀.[nl]使用一次就會壞掉,這可能使得成為歷來最低效的工具. -oc:tooltip.datacard0=提供了一些先進的演算法,如散列處理以及 deflate/inflate. -oc:tooltip.datacard1=提供了一些先進的演算法,如散列處理, AES 加密 以及 deflate/inflate. -oc:tooltip.datacard2=提供了一些先進的演算法,如散列處理, AES 加密, elliptic curve cryptography and deflate/inflate. -oc:tooltip.debugcard=創造模式物品, 它能讓你更簡易的操控世界來進行測試. 請自己承擔它帶來的危險. -oc:tooltip.debugger=可以使用輸出錯誤訊息到 OC's 網路. 只能使用在開發模式. -oc:tooltip.disassembler=拆解還原成它原來的零組件 §l警告§7: 拆解物品過程中 %s%% 有可能破壞掉這些零組件! -oc:tooltip.disk=用於制造持久存儲設備的原始媒介材料. -oc:tooltip.diskdrive.cc=已經§a支持§7使用另一個電腦模組(ComputerCraft)的軟碟. -oc:tooltip.diskdrive=用來讀寫軟碟. -oc:tooltip.diskusage=磁碟使用量: %s/%s Byte -oc:tooltip.diskmodemanaged=模式: 受管 -oc:tooltip.diskmodeunmanaged=模式: 非受管 -oc:tooltip.drone=無人機重量輕,速度快的偵察部隊,擁有有限的載貨空間。 -oc:tooltip.dronecase=這個外殼是用來建立無人機的組裝外殼。它有足夠的空間用於少量組件,並終界石供電懸浮。 -oc:tooltip.eeprom=非常小的程式化儲存裝置,可裝入電腦 BIOS 用來開機. -oc:tooltip.fakeendstone=幾乎一樣好真實的東西,甚至模仿其floatiness! -oc:tooltip.geolyzer=允許掃描周邊地區的方塊硬度,這個訊息可用於產生區域的全息圖,或用來檢測礦石是非常有用的. -oc:tooltip.graphicscard=用來改變顯示器顯示內容.[nl]最高分辨率: §f%sx%s§7[nl] 最大色深: §f%s§7 -oc:tooltip.hoverboots=跳得更高, 跌幅更深, 走得更快. 這是一個全新專利的 懸停靴 (TM). -oc:tooltip.inkcartridge=用於填充墨水的3D打印機。很神奇的原理,不必保留在印表機中。 -oc:tooltip.inkcartridgeempty=這個墨盒已經被吸乾。用染料填充它。或者把它扔掉。看看你是否在乎。 -oc:tooltip.internetcard=這個介面卡允許你發出 HTTP要求到真實的 TCP sockets. -oc:tooltip.interweb=恭喜,你贏取了 (1) 因特網,你可以使用網路卡連接它,小心,不要餵食巨魔. -oc:tooltip.ironnugget=顆粒狀的鐵,所以叫鐵粒啦,蠢蠢的感覺... -oc:tooltip.keyboard=可以連接顯示器,能夠輸入顯示文本. -oc:tooltip.hologram0=可以透過電腦進行控制以顯示任意像素體積的結構體.[nl] 解析度: §f48x32x48§7 [nl] 最大縮放: §f3x§7 [nl] 色深: §f單色§7 -oc:tooltip.hologram1=可以透過電腦進行控制以顯示任意像素體積的結構體.[nl] 解析度: §f48x32x48§7 [nl] 最大縮放: §f4x§7 [nl] 色深: §f三色§7 -oc:tooltip.linkedcard=這些都是製作成對的,而且只能與它的合作卡通訊,然而,它可以在任何距離,甚至是誇世界溝通,但是發送訊息的消耗的能量非常高. -oc:tooltip.linkedcard_channel=§8頻道: %s§7 -oc:tooltip.manual=所有你需要知道開放式電腦模組的訊息都在裡面.而且他的需求非常便宜... §o請按 R 繼續§7. -oc:tooltip.materialcosts=按著 [§f%s§7] 顯示材料成本. -oc:tooltip.materials=需求材料: -oc:tooltip.memory=電腦運行必備.[nl]記憶體越大,你就可以運行越復雜的程序. -oc:tooltip.microchip=通常也管這種芯片叫集成電路.[nl]我也不知道為啥能和紅石一起運行,但事實如此啊. -oc:tooltip.microcontroller=微控制器是一部小型電腦. 它的目的是在處理非常具體的任務, 只能執行儲存在 EEPROM 的單一獨立程式.[nl] §c無法連結外部零組件.§7 -oc:tooltip.microcontrollercase=微控制器的基本組件. 將其放入組裝機裡添加其他的零組件 -oc:tooltip.motionsensor=可以檢測到附近活物的移動,需要在視線內不能有阻擋物. -oc:tooltip.nanomachines=如果你敢,插入控制單元與一組奈米機器 -oc:tooltip.networkcard=允許通過其他方塊(比如線纜)相連的遠程計算機能夠向彼此發送信息進行交互. -oc:tooltip.poweracceptor=能源轉換速度: §f%s/t§7 -oc:tooltip.powerconverter.BuildCraft=§f建築模組minecraft焦耳(BC-MJ)§7: §a%s:%s§7 -oc:tooltip.powerconverter.Factorization=§f因式分解 (Charge)§7: §a%s:%s§7 -oc:tooltip.powerconverter.IndustrialCraft2=§f工業時代 EU(IC²-EU)§7: §a%s:%s§7 -oc:tooltip.powerconverter.Mekanism=§f通用機器焦耳(Joules)§7: §a%s:%s§7 -oc:tooltip.powerconverter.ThermalExpansion=§f熱能擴展RF(TE-RF)§7: §a%s:%s§7 -oc:tooltip.powerconverter.ResonantEngine=§f諧振引擎庫侖§7: §a%s:%s§7 -oc:tooltip.powerconverter=將其他模組的能量轉化為本模組的內部能源形式.轉換率: -oc:tooltip.powerdistributor=在不同網絡中分配能量.[nl]用來通過包含多個理論上獨立的子網絡的轉換器在系統中共享能量時很實用. -oc:tooltip.present=... for your troubles. Open this present for a chance to receive some §kphat lewt§7![nl]§8Craft OpenComputers items when the time is right for a chance to receive a present.§7 -oc:tooltip.print.BeaconBase=§8一盞燈的基座 -oc:tooltip.print.LightValue=§8發出的光: %s. -oc:tooltip.print.RedstoneLevel=§8紅石輸出: %s. -oc:tooltip.printedcircuitboard=基本的構建方塊用來裝入擴充卡與記憶體模組 -oc:tooltip.printer=允許使用玩家自定義的墨水匣 Chamelium 與 Ink Cartridges. 必須使用電腦來進行配置. 遠離小朋友 -oc:tooltip.raid=使用三個硬碟機然後連接電腦成為一個更大容量的資料儲存系統 -oc:tooltip.printedcircuitboard=擴展卡,記憶體等的基板. -oc:tooltip.rawcircuitboard=能夠在熔爐或者類似爐子中加工強化成其他材料. -oc:tooltip.redstone=能夠在方塊周圍接收以及發送紅石信號.[nl]可以被與之相連的計算機控制.基本上就像一個外置紅石卡. -oc:tooltip.redstonecard.ProjectRed=已經§a支持§fProjectRed§7. -oc:tooltip.redstonecard.RedLogic=已經§a支持§7§f紅石邏輯(RedLogic)§7中的紅石系統. -oc:tooltip.redstonecard.RedNet=已經§a支援§7MFR中的§f紅石網絡(RedNet)§7. -oc:tooltip.redstonecard.WirelessCBE=已經§a支援§f無線紅石 (ChickenBones)§7. -oc:tooltip.redstonecard.WirelessSV=已經§a支援§f無線紅石 (SlimeVoid)§7. -oc:tooltip.redstonecard=能夠在計算機和機器人四周接收以及發送紅石信號. -oc:tooltip.robot=和計算機不同,機器人能夠移動并且像玩家那些與世界之中的東西交互.[nl]然而,它們§o不能§r§7直接與外設進行交互! -# The underscore makes sure this isn't hidden with the rest of the tooltip. -oc:tooltip.robot_level=§f等級§7: §a%s§7. -oc:tooltip.robot_storedenergy=§f儲能§7: §a%s§7. -oc:tooltip.screen=由電腦機殼內的顯示卡控制來顯示文字.[nl]最高分辨率: §f%sx%s§7[nl] 最大色深: §f%s§7 -oc:tooltip.server=這是一台伺服器, 他非常棒, 但是他可以使用元件去升級他功能就像電腦一樣. 他可以插入伺服器機架上執行. -oc:tooltip.server.Components=安裝的元件: -oc:tooltip.rack=提供安裝最多達四個伺服器。為每個伺服器提供了一個內置的虛擬鍵盤和螢幕元件,相當於一個遠程終端。 -oc:tooltip.switch=允許設備相互連接不同的網絡.[nl]僅能傳遞網絡信息,通過路由器方式設備并不互相可見.[nl]例如可以通過這種方式來建立獨立網絡但仍允許其使用網卡通訊. -oc:tooltip.tablet=一台平板電腦, 可以在旅行中使用LUA. 使用潛行按鍵來啟動或是關閉他 -oc:tooltip.tabletcase=平板電腦的機殼,將它放置在機器組裝台內製作一台平板電腦 -oc:tooltip.terminal=允許遠程控制伺服器,只要你在它的範圍內。就像一個隨身型螢幕和鍵盤。按住Shift鍵並滑鼠右鍵單擊某個服務器的服務器機架終端綁定它。 -oc:tooltip.texturepicker=可以工具允許顯示方塊該面向的紋理描述, 主要用於3D印表機. 完全沒有紋理名字,沒了! -oc:tooltip.tier=§8等級 %s -oc:tooltip.netsplitter=作為一個動態連接器。每邊的連接可以通過用扳手擊中它進行切換。所有邊的連接可以通過應用紅石信號反轉。 -oc:tooltip.toolong=按住潛行鍵([§f%s§7])以查看詳細提示信息. -oc:tooltip.transistor=在多數其他計算機的零件中都很基礎的元件.[nl]引腳有點彎了,但還能用。 -oc:tooltip.transposer=允許相鄰的箱子與液體容器之間的物品液體transferral -oc:tooltip.upgradeangel=讓機器人能夠憑空放置方塊在任何地方,即使沒有參考點可以依附放置。 -oc:tooltip.upgradebattery=增加機器人可儲存的能量,讓它可以工作更長的時間不需要補充能量. [nl] 容量: §f%s§7 -oc:tooltip.upgradechunkloader=如果機器人在森林中移動,周圍沒有其他玩家,它真的會動嗎? 這個升級組件可以確保它持續地在作用中,它使區塊持續在載入狀態,但會不斷消耗能量,維持它。 -oc:tooltip.upgradecontainercard=這個集裝箱升級組件允許動態裝配機器人內的某個插卡. [nl] 最大等級: §f%s§7 -oc:tooltip.upgradecontainerupgrade=這個集裝箱升級組件允許動態裝配機器人內的某個升級組件 [nl] 最大等級: §f%s§7 -oc:tooltip.upgradecrafting=使得機器人能夠將其物品欄的左上區域作為合成網格來制做物品.[nl]物品欄內物品擺放必須與工作臺中一致. -oc:tooltip.upgradedatabase=這個升級允許儲存用於檢索與其他組件的堆疊訊息.[nl] 支持的條目: §f%s§7 -oc:tooltip.upgradeexperience=這個升級組件,能夠讓機器人執行各種操作,累積更多的經驗,然後它會獲得更多的能量,更多的儲存空間,速度更快,它收割更有效率,也能使用工具。 -oc:tooltip.upgradegenerator=用來不斷地消耗燃料發電,燃燒物品并基于它們的燃燒值隨著時間推移產生電力.[nl] §f效率§7: §a%s%%§7。 -oc:tooltip.upgradehover=可以升級可以讓機器人飛離地面更高,而且不用爬牆.[nl] 最大高度: §f%s§7 -oc:tooltip.upgradeinventory=這個升級組件提供機器人一個物品放置的空間,沒有這個升級組件,機器人將不能再內部儲存任何物品。 -oc:tooltip.upgradeinventoryController=這個升級組件可以讓機器人更好的控制如何與外部互動物品,並且允許他交換或是裝備物品欄內的工具。 -oc:tooltip.upgradeleash=允許一些設備,如無人機, 來綁定 Isaa- excuse me... *chatter* My apologies. 我只是被告知這其實是用來綁住多種動物在木樁上. -oc:tooltip.upgradenavigation=可以用來確定機器人的位置和方向。該位置是相對於被用來製作這個升級地圖的中心。 -oc:tooltip.upgradepiston=這個升級十分有用. 它能讓機器人像活塞那樣移動方塊, 但 §l不能§7 移動實體. -oc:tooltip.upgradesign=允許讀取文字與寫入文字到告示牌 -oc:tooltip.upgradesolarGenerator=在移動中可以從陽光獲取能量. 機器人上方必須保持無遮蔽狀態才能. 產生能量 %s%% 速度的能量給引擎。 -oc:tooltip.upgradetank=為你的機器人裝上一個可存儲流體的水箱. 如果沒有升級此功能, 你的機器人將無法在內部存儲流體. -oc:tooltip.upgradetankcontroller=這個升級能讓你的機器人與外界水箱交互, 向其傳輸流體. -oc:tooltip.upgradetractorbeam=裝備機器人具有非常先進的技術,綽號"物品磁鐵"。它能夠拾取三個方塊內的任何地方。 -oc:tooltip.waypoint=提供一個參考點到與導航設備的升級。 -oc:tooltip.wirelessnetworkcard=允許在發送正常信息外無線發送網絡信息.[nl]請確保已設置好§f信號強度§7否則不會發出無線數據包。 -oc:tooltip.worldsensorcard=允許讀取世界訊息,比如重力,以及是否在大氣下,傳回結果. -oc:tooltip.wrench=螺絲刀和扳手的混合體,這個工具是簡單易學,但很難掌握。 - -#Achievements -achievement.oc.adapter=插上寶寶 -achievement.oc.adapter.desc=Interact with blocks from other mods and even vanilla Minecraft! -achievement.oc.assembler=美妙 -achievement.oc.assembler.desc=Time to take over the world! -achievement.oc.cable=不是一個骯髒的電線 -achievement.oc.cable.desc=With patented anti-cable-spaghetti technology. -achievement.oc.capacitor=包括電池 -achievement.oc.capacitor.desc=You cannot stop it. -achievement.oc.card=我們接受信用卡 -achievement.oc.card.desc=For your convenience. No ulterior motive, promise. -achievement.oc.case=出現故障時 -achievement.oc.case.desc=Because cuboid towers are the best. -achievement.oc.charger=好吧,讓我們做到這一點 -achievement.oc.charger.desc=Chaaaaaaaaaarg- dang, forgot the redstone signal again. -achievement.oc.chip=所有小事 -achievement.oc.chip.desc=Because vacuum tubes are so yesteryear. -achievement.oc.cpu=超頻 -achievement.oc.cpu.desc=Time to make good use of those computing cycles. -achievement.oc.disassembler=從頭開始 -achievement.oc.disassembler.desc=In case one of your brilliant ideas turns out to be not that brilliant after all. -achievement.oc.diskDrive=環狀交叉路 -achievement.oc.diskDrive.desc=Inferior capacity but such delicious sound. -achievement.oc.drone=飛走 -achievement.oc.drone.desc=Keep calm and nuke it from orbit. -achievement.oc.eeprom=只能有1 -achievement.oc.eeprom.desc=Per computer, that is. For deterministic boot order, you know? -achievement.oc.floppy=在一個RI-磁碟 -achievement.oc.floppy.desc=Not to be confused with Flappy. -achievement.oc.geolyzer=腳踏實地 -achievement.oc.geolyzer.desc=It has extraordinary qualities. -achievement.oc.graphicsCard=LastGen -achievement.oc.graphicsCard.desc=The way it's meant to be... uh... rendered. Yeah. That. -achievement.oc.hdd=熱狗經銷商 -achievement.oc.hdd.desc=No wait, that's not what that meant. Hang on, almost got it... -achievement.oc.hologram=下一個維度 -achievement.oc.hologram.desc=Because 2D is boring. Or is it? -achievement.oc.keyboard=DirtCatcher3000 -achievement.oc.keyboard.desc=It is highly recommended to resist the urge to flip them around and shake them. -achievement.oc.microcontroller=小妹妹 -achievement.oc.microcontroller.desc=The small sibling of computers. -achievement.oc.motionSensor=能動 -achievement.oc.motionSensor.desc=Like Steve Swagger. -achievement.oc.networkCard=現在我們談論! -achievement.oc.networkCard.desc=Keep in touch with those distant relatives via transitive relations. -achievement.oc.openOS=開機 -achievement.oc.openOS.desc=One OS to - wait, I used that one already? Dang. -achievement.oc.powerDistributor=共享是關懷 -achievement.oc.powerDistributor.desc=When you need some help balancing all that power. -achievement.oc.rack=Dat Rack -achievement.oc.rack.desc=I don't know what you're thinking of, I clearly meant the server rack. -achievement.oc.raid=LFG -achievement.oc.raid.desc=Heroic plzkthx. -achievement.oc.ram=隨機存取存儲器 -achievement.oc.ram.desc=Congratulations, you're Doin' It Right. -achievement.oc.redstoneCard=聯繫 -achievement.oc.redstoneCard.desc=Time to go analog. -achievement.oc.redstoneIO=局外人 -achievement.oc.redstoneIO.desc=Taking redstone signals where you want them. -achievement.oc.robot=嗶布普 -achievement.oc.robot.desc=EXTERMINATE! -achievement.oc.screen=Have you tried turning it off and on again? -achievement.oc.screen.desc=No seriously. A redstone pulse can toggle a screen's power, after all. -achievement.oc.server=專用 -achievement.oc.server.desc=雲服務,我們來了。 -achievement.oc.switch=複雜的拓撲 -achievement.oc.switch.desc=避免易碎物品因遺失資料的可能性。 -achievement.oc.tablet=不要嚥下 -achievement.oc.tablet.desc=Also keep away from small children to avoid unexpected overdrawing of your credit card. -achievement.oc.transistor=告訴紅石說:“你好。” -achievement.oc.transistor.desc=Create a Transistor to get started. Then listen to the soundtrack. No need to thank me. -achievement.oc.wirelessNetworkCard=信號 -achievement.oc.wirelessNetworkCard.desc=Time to go where no packet has gone before. - -# Death messages. Note that the number of entries here must match the number -# set in the actual damage source in code. -death.attack.oc.nanomachinesOverload.1=%s 獲得貪婪稱號。 -death.attack.oc.nanomachinesOverload.2=%s 神經衰弱。 -death.attack.oc.nanomachinesOverload.3=奈米機器 %s 失去控制 -death.attack.oc.nanomachinesHungry.1=%s 被奈米機器吃掉 -death.attack.oc.nanomachinesHungry.2=%s 沒有定時餵食奈米機器 -death.attack.oc.nanomachinesHungry.3=%s 已被消化。 - -# NEI Integration -nei.options.inventory.oredict=顯示礦物字典名稱 -nei.options.inventory.oredict.true=真 -nei.options.inventory.oredict.false=假 -nei.usage.oc.Manual=打開手冊 - -# Waila Integration -option.oc.address=位址 -option.oc.componentName=組件名稱 -option.oc.energy=能源 diff --git a/src/main/resources/assets/opencomputers/lang/zh_cn.json b/src/main/resources/assets/opencomputers/lang/zh_cn.json new file mode 100644 index 0000000000..7d07804ac0 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/zh_cn.json @@ -0,0 +1,454 @@ +{ + "tile.oc.adapter": "适配器", + "tile.oc.assembler": "装配器", + "tile.oc.cable": "线缆", + "tile.oc.capacitor": "电容", + "tile.oc.carpetedcapacitor": "踩踏发电电容", + "tile.oc.case1": "基础机箱", + "tile.oc.case2": "高级机箱", + "tile.oc.case3": "超级机箱", + "tile.oc.casecreative": "创造模式机箱", + "tile.oc.chameliumblock": "变色块", + "tile.oc.charger": "充电器", + "tile.oc.disassembler": "拆解器", + "tile.oc.diskdrive": "软盘驱动器", + "tile.oc.endstone": "末地石", + "tile.oc.geolyzer": "地质分析仪", + "tile.oc.hologram1": "基础全息地图投影仪", + "tile.oc.hologram2": "高级全息地图投影仪", + "tile.oc.keyboard": "键盘", + "tile.oc.microcontroller": "单片机", + "tile.oc.motionsensor": "运动传感器", + "tile.oc.netsplitter": "网络分配器", + "tile.oc.powerconverter": "能量转换器", + "tile.oc.powerdistributor": "能量分配器", + "tile.oc.print": "3D 打印", + "tile.oc.printer": "3D 打印机", + "tile.oc.raid": "Raid磁盘阵列", + "tile.oc.redstone": "红石 I/O 端口", + "tile.oc.relay": "中继器", + "tile.oc.robot": "机器人", + "tile.oc.robotafterimage": "机器人", + "tile.oc.screen1": "基础显示屏", + "tile.oc.screen2": "高级显示屏", + "tile.oc.screen3": "超级显示屏", + "tile.oc.rack": "机架", + "tile.oc.transposer": "转运器", + "tile.oc.waypoint": "路径点", + "item.oc.abstractbuscard": "抽象类总线卡", + "item.oc.acid": "酸液", + "item.oc.alu": "算术逻辑单元(ALU)", + "item.oc.analyzer": "分析器", + "item.oc.apu0": "高级加速运算单元(APU)", + "item.oc.apu1": "超级加速运算单元(APU)", + "item.oc.apu2": "创造加速运算单元(APU)", + "item.oc.arrowkeys": "方向键", + "item.oc.buttongroup": "按钮组", + "item.oc.cardbase": "基板", + "item.oc.chamelium": "变色材料", + "item.oc.circuitboard": "电路板", + "item.oc.componentbus0": "基础组件总线", + "item.oc.componentbus1": "高级组件总线", + "item.oc.componentbus2": "超级组件总线", + "item.oc.componentbus3": "创造模式组件总线", + "item.oc.controlunit": "控制单元(CU)", + "item.oc.cpu0": "基础中央处理器(CPU)", + "item.oc.cpu1": "高级中央处理器(CPU)", + "item.oc.cpu2": "超级中央处理器(CPU)", + "item.oc.cuttingwire": "切割线", + "item.oc.datacard0": "基础数据卡", + "item.oc.datacard1": "高级数据卡", + "item.oc.datacard2": "超级数据卡", + "item.oc.debugcard": "调试卡", + "item.oc.debugger": "网络调试器", + "item.oc.diamondchip": "钻石芯片", + "item.oc.disk": "磁碟", + "item.oc.diskdrivemountable": "可挂载软盘驱动器", + "item.oc.drone": "无人机", + "item.oc.dronecase0": "基础无人机外壳", + "item.oc.dronecase1": "高级无人机外壳", + "item.oc.dronecase3": "创造无人机外壳", + "item.oc.eeprom": "EEPROM", + "item.oc.floppydisk": "软盘", + "item.oc.GraphicsCard0": "基础显卡", + "item.oc.GraphicsCard1": "高级显卡", + "item.oc.GraphicsCard2": "超级显卡", + "item.oc.HardDiskDrive0": "基础磁盘驱动器", + "item.oc.HardDiskDrive1": "高级磁盘驱动器", + "item.oc.HardDiskDrive2": "超级磁盘驱动器", + "item.oc.hoverBoots": "悬浮靴", + "item.oc.inkcartridge": "墨盒", + "item.oc.inkcartridgeempty": "空墨盒", + "item.oc.internetcard": "因特网卡", + "item.oc.Interweb": "因特网", + "item.oc.ironnugget": "铁粒", + "item.oc.linkedcard": "连接卡", + "item.oc.manual": "开放式电脑使用手册", + "item.oc.memory0": "内存条-T1", + "item.oc.memory1": "内存条-T1.5", + "item.oc.memory2": "内存条-T2", + "item.oc.memory3": "内存条-T2.5", + "item.oc.memory4": "内存条-T3", + "item.oc.memory5": "内存条-T3.5", + "item.oc.microchip0": "简易微芯片", + "item.oc.microchip1": "高级微芯片", + "item.oc.microchip2": "超级微芯片", + "item.oc.microcontrollercase0": "基础单片机外壳", + "item.oc.microcontrollercase1": "高级单片机外壳", + "item.oc.microcontrollercase3": "创造单片机外壳", + "item.oc.nanomachines": "纳米机器", + "item.oc.networkcard": "网卡", + "item.oc.numpad": "数字键盘", + "item.oc.present": "一点小礼物……", + "item.oc.printedcircuitboard": "印刷电路板(PCB)", + "item.oc.rawcircuitboard": "未加工电路板", + "item.oc.redstonecard0": "基础红石卡", + "item.oc.redstonecard1": "高级红石卡", + "item.oc.server0": "基础服务器", + "item.oc.server1": "高级服务器", + "item.oc.server2": "超级服务器", + "item.oc.server3": "创造模式服务器", + "item.oc.tablet": "平板电脑", + "item.oc.tabletcase0": "基础平板电脑外壳", + "item.oc.tabletcase1": "高级平板电脑外壳", + "item.oc.tabletcase3": "创造模式平板电脑外壳", + "item.oc.terminal": "终端", + "item.oc.terminalserver": "终端服务器", + "item.oc.texturepicker": "纹理选择器", + "item.oc.transistor": "晶体管", + "item.oc.upgradeangel": "天使方块升级", + "item.oc.upgradebattery0": "基础电池升级", + "item.oc.upgradebattery1": "高级电池升级", + "item.oc.upgradebattery2": "超级电池升级", + "item.oc.upgradechunkloader": "区块载入升级", + "item.oc.upgradecontainercard0": "基础卡槽", + "item.oc.upgradecontainercard1": "高级卡槽", + "item.oc.upgradecontainercard2": "超级卡槽", + "item.oc.upgradecontainerupgrade0": "基础升级组件容器", + "item.oc.upgradecontainerupgrade1": "高级升级组件容器", + "item.oc.upgradecontainerupgrade2": "超级升级组件容器", + "item.oc.upgradecrafting": "合成升级", + "item.oc.upgradedatabase0": "基础数据库升级", + "item.oc.upgradedatabase1": "高级数据库升级", + "item.oc.upgradedatabase2": "超级数据库升级", + "item.oc.upgradeexperience": "经验升级", + "item.oc.upgradegenerator": "发电机升级", + "item.oc.upgradehover0": "基础悬浮升级", + "item.oc.upgradehover1": "高级悬浮升级", + "item.oc.upgradeinventory": "物品栏升级", + "item.oc.upgradeinventorycontroller": "物品栏控制器升级", + "item.oc.upgradeleash": "缰绳升级", + "item.oc.upgrademf": "MFU", + "item.oc.upgradenavigation": "导航升级", + "item.oc.upgradepiston": "活塞升级", + "item.oc.upgradesign": "告示牌读写升级", + "item.oc.upgradesolargenerator": "太阳能发电机升级", + "item.oc.upgradetank": "水箱升级", + "item.oc.upgradetankcontroller": "储罐升级", + "item.oc.upgradetractorbeam": "牵引光束升级", + "item.oc.upgradetrading": "交易升级", + "item.oc.wirelessnetworkcard0": "基础无线网卡", + "item.oc.wirelessnetworkcard1": "高级无线网卡", + "item.oc.worldsensorcard": "世界传感器卡", + "item.oc.wrench": "螺丝刀扳手", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.Drone": "无人机", + "oc:gui.Analyzer.Address": "§6地址§f:%s", + "oc:gui.Analyzer.AddressCopied": "地址已复制到剪贴板。", + "oc:gui.Analyzer.ChargerSpeed": "§6充电速度§f:%s", + "oc:gui.Analyzer.ComponentName": "§6组件名§f:%s", + "oc:gui.Analyzer.Components": "§6已连接组件的数量§f:%s", + "oc:gui.Analyzer.CopyToClipboard": "点击以复制到剪贴板。", + "oc:gui.Analyzer.LastError": "§6上一个错误§f:%s", + "oc:gui.Analyzer.RobotName": "§6名称§f:%s", + "oc:gui.Analyzer.RobotOwner": "§6主人§f:%s", + "oc:gui.Analyzer.RobotXp": "§6经验§f:%s(等级 %s)", + "oc:gui.Analyzer.StoredEnergy": "§6存储能量§f:%s", + "oc:gui.Analyzer.TotalEnergy": "§6存储能量上限§f:%s", + "oc:gui.Analyzer.Users": "§6用户§f:%s", + "oc:gui.Analyzer.WirelessStrength": "§6信号强度§f:%s", + "oc:gui.Assembler.Collect": "收集输出", + "oc:gui.Assembler.Complexity": "复杂度:%s/%s", + "oc:gui.Assembler.InsertCase": "插入一个机箱", + "oc:gui.Assembler.InsertCPU": "插入一个CPU", + "oc:gui.Assembler.InsertRAM": "插入一些存储器", + "oc:gui.Assembler.Progress": "进度:%s%%(%s)", + "oc:gui.Assembler.Run": "组装", + "oc:gui.Assembler.Warning.BIOS": "BIOS", + "oc:gui.Assembler.Warning.GraphicsCard": "显卡", + "oc:gui.Assembler.Warning.Inventory": "物品栏升级", + "oc:gui.Assembler.Warning.Keyboard": "键盘", + "oc:gui.Assembler.Warning.OS": "运行环境", + "oc:gui.Assembler.Warning.Screen": "显示屏", + "oc:gui.Assembler.Warnings": "§e警告§7:推荐的组件丢失。", + "oc:gui.Chat.NewVersion": "有新版本可用:%s", + "oc:gui.Chat.TextureName": "§7材质名为§a%s§f。", + "oc:gui.Chat.WarningClassTransformer": "执行类转换器时发生§c错误§f。请务必反馈此问题,反馈时一并附上 FML 的日志文件 §alatest.log/fml-server-latest.log§f,谢谢!", + "oc:gui.Chat.WarningFingerprint": "§c警告§f——指纹校验不匹配!应为 '§a%s§f',实为 '§e%s§f'。如果你不是在反混淆环境下运行游戏的模组开发者,我们§l强烈§f建议你重新下载开放式电脑模组,因为你现在使用的 JAR 文件已被修改。", + "oc:gui.Chat.WarningLink": "无法打开链接:%s", + "oc:gui.Chat.WarningLuaFallback": "无法使用原生 Lua 库,电脑无法持久化当前状态。它们会在区块载入时重启。", + "oc:gui.Chat.WarningProjectRed": "你目前使用的 Project:Red 版本不兼容 OpenComputers,请更新 Project:Red。", + "oc:gui.Chat.WarningRecipes": "加载合成表时遇到一个或多个错误。部分物品或因此无法合成。查阅日志文件以获取详细信息。", + "oc:gui.Drive.Managed": "受管理", + "oc:gui.Drive.Unmanaged": "不受管理", + "oc:gui.Drive.ReadOnlyLock": "只读锁定", + "oc:gui.Drive.ReadOnlyLockWarning": "§l只读§r锁定.除非抹掉该磁盘,否则无法关闭.", + "oc:gui.Drive.Warning": "§l警告§r:切换模式将会导致当前磁盘上所有数据丢失!", + "oc:gui.Error.ComponentOverflow": "过多的组件连接了计算机。", + "oc:gui.Error.InternalError": "内部错误,请检查日志文件。这可能是个Bug。", + "oc:gui.Error.NoCPU": "这台计算机上没有安装CPU。", + "oc:gui.Error.NoEnergy": "能量不足。", + "oc:gui.Error.NoRAM": "这台计算机上没有安装内存。", + "oc:gui.Error.OutOfMemory": "内存溢出。", + "oc:gui.Manual.Blocks": "开放式电脑-方块", + "oc:gui.Manual.Home": "主页", + "oc:gui.Manual.Items": "开放式电脑-物品", + "oc:gui.Manual.Warning.BlockMissing": "该方块不可用。", + "oc:gui.Manual.Warning.ImageMissing": "未找到图片。", + "oc:gui.Manual.Warning.ItemMissing": "该物品不可用。", + "oc:gui.Manual.Warning.OreDictMissing": "该矿物词典条目不可用。", + "oc:gui.Raid.Warning": "§4添加磁盘会抹掉该磁盘。\n移除磁盘会使Raid无法使用。", + "oc:gui.Robot.Power": "能量", + "oc:gui.Robot.TurnOff": "关闭", + "oc:gui.Robot.TurnOn": "开启\n§7使用分析器来追踪错误。§r", + "oc:gui.ServerRack.Back": "后", + "oc:gui.ServerRack.Bottom": "底部", + "oc:gui.ServerRack.Left": "左", + "oc:gui.ServerRack.None": "无", + "oc:gui.ServerRack.Right": "右", + "oc:gui.Rack.Enabled": "启用", + "oc:gui.Rack.Disabled": "禁用", + "oc:gui.ServerRack.Top": "上", + "oc:gui.Switch.PacketsPerCycle": "数据包 / 周期", + "oc:gui.Switch.QueueSize": "队列长度", + "oc:gui.Switch.TransferRate": "传输速率", + "oc:gui.Terminal.InvalidKey": "无效键,看上去另一个终端已绑定到这台服务器。", + "oc:gui.Terminal.OutOfRange": "无信号。", + "oc:container.adapter": "适配器", + "oc:container.case": "计算机", + "oc:container.charger": "充电器", + "oc:container.disassembler": "分解器", + "oc:container.diskdrive": "磁盘驱动器", + "oc:container.printer": "打印机", + "oc:container.raid": "Raid磁盘阵列", + "oc:container.relay": "中继器", + "oc:container.server": "服务器", + "oc:container.rack": "机架", + "oc:container.tabletwrapper": "平板电脑", + "key.opencomputers.clipboardPaste": "粘贴到剪贴板", + "oc:tooltip.abstractbuscard": "允许计算机向§f星门科技2§7的抽象类总线发送或接收 LIP 数据包。", + "oc:tooltip.acid": "一种有毒的虚构液体,通常只有某些海盗会使用它们。然而它应该有别的用途。", + "oc:tooltip.adapter": "用于控制非电脑组件的方块,比如原版或者来自其它模组的方块。", + "oc:tooltip.alu": "用来做算术及逻辑运算而不用你亲自代劳,它更能胜任这份差事。", + "oc:tooltip.analyzer": "用于显示方块信息,比如它们的§f地址§7和§f组件名称§7。如果计算机未能正常关闭它也会显示使计算机崩溃的报错。", + "oc:tooltip.apu": "如果你只是需要一个额外的卡槽,这就是你需要的自带 GPU(或者集成图形处理器 IGP)的 CPU。\n支持的组件:§f%s§7\n最大分辨率:§f%sx%s§7\n最高色深:§f%s§7\n运算/tick:§f%s§7", + "oc:tooltip.assembler": "允许使用若干不同的电脑组件来组装机器人。", + "oc:tooltip.cable": "连接方块的廉价选择。", + "oc:tooltip.capacitor": "储能以备不时之需。能够非常快速地充电或放电。", + "oc:tooltip.carpetedcapacitor": "储能以备不时之需。能够非常快速地充电或放电。有羊或豹猫踩上去的时候就能充电。", + "oc:tooltip.cardbase": "正如其名,它是用来安装其它扩展卡的基本卡板。", + "oc:tooltip.case": "计算机机箱是构建计算机的基本方块,也是各种§f扩展卡§7,§f存储器§7以及§f硬盘§7的外壳。\n格子:§f%s§7", + "oc:tooltip.chamelium": "3D打印的基本原材料。不要误吸:或造成失明和暂时失去意识。", + "oc:tooltip.chameliumblock": "整洁干净的玩意。对于彩色 3D 打印相当实用,或者只是拿它的整洁干净的色彩来装饰你的华丽的基地。", + "oc:tooltip.charger": "将电容器的能量传输给相邻机器人。传输效率取决于输入的§f红石信号§7强度,无信号意味着不给机器人充电,而最强信号则意味着全速给机器人充电。", + "oc:tooltip.circuitboard": "现在我们已经取得一些进展。可以通过蚀刻来得到印制电路板。", + "oc:tooltip.controlunit": "用来控制……控制东西……的单元。你需要这玩意儿来做 CPU。所以反正啦,这个非常重要。", + "oc:tooltip.componentbus": "这个扩展能让服务器同时与更多组件通讯,工作原理类似 CPU。\n支持的组件:§f%s§7", + "oc:tooltip.cpu": "所有计算机最核心的组件,它的时钟频率有点不可靠,但是你考虑到它是靠便携日晷来运行的,还能指望什么呢?\n支持组件:§f%s§7", + "oc:tooltip.cpu.Architecture": "架构:§f%s§7", + "oc:tooltip.cuttingwire": "用于将粘土块切割成电路板的形状。使用一次就会坏掉,这可能使得成为历来最低效的工具。", + "oc:tooltip.datacard0": "提供数种高级算法,例如散列、压缩和解压缩算法。", + "oc:tooltip.datacard1": "提供数种高级算法,例如散列、AES 加密、压缩和解压缩算法。", + "oc:tooltip.datacard2": "提供数种高级算法,例如散列、AES 加密、椭圆曲线加密、压缩和解压缩算法。", + "oc:tooltip.debugcard": "创造模式物品,它能让你更简易的操控世界来进行测试。请自己承担它带来的危险。", + "oc:tooltip.debugger": "用于在 OpenComputer 的内部网络格栅中输出调试信息。请在开发者指导下使用。", + "oc:tooltip.diamondchip": "一小粒正在发光的钻石。永远不会破镜重圆。", + "oc:tooltip.disassembler": "将物品分解成基础组件。§l警告§7:分解得到的物品会有 %s%% 的几率在分解过程中损坏!", + "oc:tooltip.disk": "用于制造持久存储设备的原始媒介材料。", + "oc:tooltip.diskdrive.CC": "§a支持§7 ComputerCraft 的软盘。", + "oc:tooltip.diskdrive": "用来读写软盘。可以给机器人安装使其可以插入软盘。", + "oc:tooltip.diskdrivemountable": "和普通软驱用途一样,但必须装载在机架里。", + "oc:tooltip.diskusage": "磁盘使用:%s/%s 字节", + "oc:tooltip.diskmodemanaged": "模式:管理", + "oc:tooltip.diskmodeunmanaged": "模式:不受管理", + "oc:tooltip.drone": "无人机是一种轻量而快速的侦查单位,自身拥有有限的载物空间。", + "oc:tooltip.dronecase": "这个外壳将会在组装机中组装出无人机。这个外壳可容纳少量组件,并内建末地石驱动的悬浮系统。", + "oc:tooltip.eeporm": "小型的可编程存储器,可存储电脑启动所用的BIOS。", + "oc:tooltip.fakeendstone": "几乎可以以假乱真,甚至更加轻盈!", + "oc:tooltip.geolyzer": "可以检测周围方块的硬度。这些信息对编写全息地图程序或检测矿物都有很大的帮助。", + "oc:tooltip.graphicscard": "用来改变屏幕上的显示内容。最高分辨率:§f%sx%s§7\n最高色深:§f%s§7\n运算/tick:§f%s§7", + "oc:tooltip.hoverboots": "跳得更高,摔得更深,走得更快。一切尽在 Hover Boots™,已获顶级认证。", + "oc:tooltip.inkcartridge": "用于重新填装3D打印机的墨水。因为某些原因这些墨水不必保留在打印机里。", + "oc:tooltip.inkcartridgeempty": "此墨盒经过深度干燥处理。用颜料重新装填,抑或弃置。看我脸色行事。", + "oc:tooltip.internetcard": "因特网卡可以让你发送HTTP请求以及使用货真价实的TCP套接字。", + "oc:tooltip.interweb": "恭喜,你赢得了一个因特网。你可以使用因特网卡来连接它。注意:不要水贴钓鱼", + "oc:tooltip.ironnugget": "颗粒状的铁,所以叫铁粒啦,蠢蠢的感觉……", + "oc:tooltip.keyboard": "可以连接屏幕来输入显示文本。", + "oc:tooltip.hologram0": "一个能通过电脑控制来投射出任何三维结构的全息投影仪.\n分辨率:§f48x32x48§7\n最大显示规模:§f3x§7\n最高色深:§f黑白§7", + "oc:tooltip.hologram1": "使用电脑控制的高级全息投影仪。\n分辨率:§f48x32x48§7\n最大显示规模:§f4x§7\n最高色深:§f三原色§7", + "oc:tooltip.linkedcard": "连接卡可以成对合成,并且它们只能与各自对应的连接卡交互。然而,它们之间的交互没有距离限制,甚至可以跨越不同的世界。但它们传递信息所需要的能量消耗不多不少。", + "oc:tooltip.linkedcard_channel": "§8频道:%s§7", + "oc:tooltip.manual": "包含你需要的关于 OpenComputer 的一切信息。还有更多。为此你只需要……§o请按R键继续§7。", + "oc:tooltip.memory": "电脑运行必备。内存越大,你就可以运行越复杂的程序。", + "oc:tooltip.microchip": "通常也管这种芯片叫集成电路。我也不知道为什么能和红石一起运行,但事实如此。", + "oc:tooltip.microcontroller": "单片机是被压缩到不能再压缩的电脑。它们更多是用于执行特殊任务,并只运行一个内建于EEPROM中的简单程序。\n§c不能和外置组件相连接。§7", + "oc:tooltip.microcontrollercase": "单片机基础组件。在组装机中为其添加各种组件并组装单片机。", + "oc:tooltip.motionsensor": "可以检测附近生物的动向。检测需要无遮挡物的环境。", + "oc:tooltip.nanomachines": "控制单元,同时还是一堆可以吸入的纳米机器(如果你愿意的话)。", + "oc:tooltip.networkcard": "允许通过其他方块(比如线缆)相连的远程计算机能够向彼此发送信息进行交互。", + "oc:tooltip.poweracceptor": "能量转换速度:§f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§fMJ§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§fCharge§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§fEU§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§fJoules§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§fRF§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§fCoulombs§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "将其它模组的能量转化为本模组的内部能源形式。转换比:", + "oc:tooltip.powerdistributor": "在不同网络中分配能量。很实用于通过包含多个理论上独立子网络的转换器在系统中共享能量。", + "oc:tooltip.present": "……它随时为你的麻烦待命。打开此礼物将有机会获得 §kphat lewt§7!\n§8在时机合适时,合成 OpenComputers 的物品。§7", + "oc:tooltip.print.BeaconBase": "§8可用作信标底座。", + "oc:tooltip.print.LightValue": "§8光强:%s。", + "oc:tooltip.print.RedstoneLevel": "§8红石信号强度:%s。", + "oc:tooltip.printedcircuitboard": "扩展卡、内存等组件的基础板。", + "oc:tooltip.printer": "利用变色物质和墨盒打印出用户自定义的形状。需要用电脑进行配置。不要让幼童接触。就是这样。", + "oc:tooltip.raid": "允许将三块硬盘组成一个大文件系统供所有与其连接的电脑使用。", + "oc:tooltip.rawcircuitboard": "能在支持原版熔炉配方的炉子中加工强化。", + "oc:tooltip.redstone": "能够在方块周围接收或发送红石信号。可以被与之相连的计算机控制。基本上就像一个外置红石卡。", + "oc:tooltip.redstonecard.Charset": "§a兼容§7 §fSimpleLogic§7。", + "oc:tooltip.redstonecard.ProjectRed": "§a兼容§7 §fProject Red§7。", + "oc:tooltip.redstonecard.RedLogic": "§a兼容§7 §fRedLogic§7。", + "oc:tooltip.redstonecard.RedNet": "§a兼容§7 §fRedNet§7。", + "oc:tooltip.redstonecard.WirelessCBE": "§a兼容§7 §f无线红石(ChickenBones)§7。", + "oc:tooltip.redstonecard.WirelessSV": "§a兼容§7 §f无线红石(SlimeVoid)§7。", + "oc:tooltip.redstonecard": "允许在计算机和机器人四周接收或发送红石信号。", + "oc:tooltip.relay": "可将不同网络连接在一起。仅信息可通过此设备传递,其它元件仍不可见。用法举例:可用于保持多个独立网络的通信。", + "oc:tooltip.robot": "和计算机不同,机器人能够移动并且像玩家那样与世界中的东西交互。然而,它们§o不能§r§7直接与外设进行交互!", + "oc:tooltip.robot_level": "§f等级§7:§a%s§7。", + "oc:tooltip.robot_storedenergy": "§f存储能量§7:§a%s§7。", + "oc:tooltip.screen": "显示文本,运作需要机箱中的显卡。\n最高分辨率:§f%sx%s§7\n最高色深:§f%s§7", + "oc:tooltip.server": "这就是服务器,它与许多其它的服务器拥有相似功能,但这台服务器可以使用组件进行升级,就像升级机箱一样。它也可以放入服务器机架中运行。", + "oc:tooltip.server.Components": "已安装的组件:", + "oc:tooltip.rack": "它能装下四台服务器或者别的设备。", + "oc:tooltip.tablet": "一台平板电脑,为 Lua 新人准备。潜行时右击可强制关机。", + "oc:tooltip.tabletcase": "平板电脑的基础外壳。在组装机中添加组件以制造平板电脑。", + "oc:tooltip.terminal": "可以远程控制服务器,不过前提是你处于信号范围内。使用方法相同于显示屏与键盘. Shift 右击机架中的服务器可以绑定对应的终端。", + "oc:tooltip.terminalserver": "在工作范围内可与终端连接,以提供远程控制功能。内建有虚拟显示器和键盘。", + "oc:tooltip.texturepicker": "这个工具可以显示放块表面的描述,可用于3D打印定义中。完全不是材质名,完全不是。很抱歉先生,不是。", + "oc:tooltip.tier": "§8等级 %s", + "oc:tooltip.netsplitter": "作为动态连接器的存在。每个面的连接设定可通过扳手切换。红石信号可反相所有面的连接设定。", + "oc:tooltip.toolong": "按住 [§f%s§7] 显示详细物品信息。", + "oc:tooltip.transistor": "大多数电脑组件中最基础的元素。看上去有些扭曲,但它是有用的。", + "oc:tooltip.transposer": "可在相邻容器之间自动转移物品和液体。", + "oc:tooltip.upgradeangel": "允许机器人凭空放置方块,甚至是在没有任何依附的情况下。", + "oc:tooltip.upgradebattery": "增加机器人存储能量的上限,让其能够运作很长一段时间也不必充电。\n电容:§f%s§7", + "oc:tooltip.upgradechunkloader": "如果机器人走进了一片森林,周围没有任何生物载入区块,那么它还能继续移动吗? 这个升级组件可以让你确定这点。它能让机器人所处的区块保持载入,但这会让能量不断地消耗。", + "oc:tooltip.upgradecontainercard": "卡容器组件可以让你方便随意的将卡装入机器人或从中移出。\n最高等级:§f%s§7", + "oc:tooltip.upgradecontainerupgrade": "卡容器升级组件可以让你方便的将卡装入另一个卡容器或从中移出。\n最高等级:§f%s§7", + "oc:tooltip.upgradecrafting": "能让机器人的物品栏左上角部分成为合成界面。物品必须在合成界面里排列整齐。", + "oc:tooltip.upgradedatabase": "能对物品信息进行分类,供其它组件稍后取用。\n可支持条目数量:§f%s§7", + "oc:tooltip.upgradeexperience": "这个升级能让机器人在执行一些工作时获取经验并累积。它们拥有越多的累积经验,就能够存储越多的能量,越快的挖掘方块并且使用工具时拥有更高的效率。", + "oc:tooltip.upgradegenerator": "可以让机器人通过燃料充能。燃烧物品得到的发电量取决于燃料的等级。\n§f发电效率§7:§a%s%%§7", + "oc:tooltip.upgradehover": "这个升级组件可让机器人飞得更高而无需爬墙。\n最大高度:§f%s§7", + "oc:tooltip.upgradeinventory": "这个升级组件为机器人提供了物品背包。如果没有这个升级,机器人将不能存储物品。", + "oc:tooltip.upgradeinventorycontroller": "这个升级组件可以控制机器人使其与外部容器互动,并能允许机器人将装备上的工具替换成其物品栏中的其它物品。", + "oc:tooltip.upgrademf": "能让适配器访问不与其相邻的方块。", + "oc:tooltip.upgrademf.Linked": "§f已连接§7", + "oc:tooltip.upgrademf.Unlinked": "§f没有连接§7", + "oc:tooltip.upgradeleash": "这个升级组件可让诸如无人机之类的设备绑在 Isaa——不好意思,*清清嗓子* 我刚才说错了。我只是被告知这原本是用来拴动物的绳子。可以拴很多动物,好奇怪啊。", + "oc:tooltip.upgradenavigation": "可以让机器人确认所处位置以及定位。定位地点即为用于合成此升级组件用到的地图的中心点。", + "oc:tooltip.upgradepiston": "这个升级十分有用。它能让机器人像活塞那样移动方块,但 §l不能§7 移动实体。", + "oc:tooltip.upgradesign": "允许机器人读写告示牌。", + "oc:tooltip.upgradesolargenerator": "可以让机器人在太阳光的照射下四处奔走。机器人顶部需要无任何方块阻挡。产能速度是斯特林引擎的 %s%%。", + "oc:tooltip.upgradetank": "为你的机器人装上一个可存储流体的水箱。如果没有升级此功能,你的机器人将无法在内部存储流体。", + "oc:tooltip.upgradetankcontroller": "这个升级能让你的机器人与外界水箱交互,向其传输流体。", + "oc:tooltip.upgradetractorbeam": "十分先进的高科技,别名“物品磁铁”。它能让机器人在任何地方捡起3格范围内的掉落物。", + "oc:tooltip.waypoint": "为安装有导航升级的设备提供参考点。", + "oc:tooltip.wirelessnetworkcard": "允许在发送正常信息的情况下发送无线网络信息。请确保已设置好 §f信号强度§7 否则不会发出信息。越高的信号强度会导致越高的能量消耗。", + "oc:tooltip.worldsensorcard": "可读取关于世界的各种信息,例如重力加速度和是否有可供呼吸的大气。使用风险自负。制造商对由卡片输出结果造成的损失不承担任何法律责任。我们不仅有律师,还有现金。不要试图告倒我们。", + "oc:tooltip.wrench": "螺丝刀和扳手混合体,新手友好,高手毁灭者。", + "achievement.oc.adapter": "Plug In Baby", + "achievement.oc.adapter.desc": "和其它 MOD 的方块(甚至是原版 Minecraft 方块)进行互动!", + "achievement.oc.assembler": "完美", + "achievement.oc.assembler.desc": "是时候征服世界了!", + "achievement.oc.cable": "并不是脏兮兮的电线", + "achievement.oc.cable.desc": "搭配权威认证的反 SCP-229 科技", + "achievement.oc.capacitor": "本设备含电池", + "achievement.oc.capacitor.desc": "不可能阻止它", + "achievement.oc.card": "我们接受卡片", + "achievement.oc.card.desc": "这是为方便您的使用。我们保证这不是别有用心。", + "achievement.oc.case": "以备后患", + "achievement.oc.case.desc": "Because cuboid towers are the best.", + "achievement.oc.charger": "那就开始做吧!", + "achievement.oc.charger.desc": "开始充——等等!又忘记红石信号了。", + "achievement.oc.chip": "全是些小东西", + "achievement.oc.chip.desc": "曾经真空管也是这样的。", + "achievement.oc.cpu": "超频", + "achievement.oc.cpu.desc": "是时候好好利用这些计算循环了", + "achievement.oc.disassembler": "销毁!", + "achievement.oc.disassembler.desc": "当你发现你的想法很美好,但现实其实很残酷的时候,就用这个吧。", + "achievement.oc.diskDrive": "Roundabout", + "achievement.oc.diskDrive.desc": "Inferior capacity but such delicious sound.", + "achievement.oc.drone": "啊!飞走了!", + "achievement.oc.drone.desc": "冷静冷静,直接用核弹让他们在轨道上瞬间爆炸", + "achievement.oc.eeprom": "每台电脑", + "achievement.oc.eeprom.desc": "仅限一个,就是这样。这是用来决定最终启动顺序的,明白吗!?", + "achievement.oc.floppy": "The One Ri- Disk", + "achievement.oc.floppy.desc": "不要与flappy混淆。\n注:软盘英文为floppy disk", + "achievement.oc.geolyzer": "深入地心", + "achievement.oc.geolyzer.desc": "It has extraordinary qualities.", + "achievement.oc.graphicsCard": "LastGen", + "achievement.oc.graphicsCard.desc": "The way it's meant to be... uh... rendered. Yeah. That.", + "achievement.oc.hdd": "Hot Dog Dealer(热狗推销员)", + "achievement.oc.hdd.desc": "等等我不是那个意思。让我想想,好像想起来什么意思了……", + "achievement.oc.hologram": "下一个次元", + "achievement.oc.hologram.desc": "因为 2D 很无聊啊。或者本来就这样?", + "achievement.oc.keyboard": "吸尘器 3000 型", + "achievement.oc.keyboard.desc": "强烈建议使用时保持将其翻过来并持续摇晃的习惯,以清理其中异物。", + "achievement.oc.microcontroller": "Little Sisters", + "achievement.oc.microcontroller.desc": "计算机的小妹妹哦", + "achievement.oc.motionSensor": "Got the Moves", + "achievement.oc.motionSensor.desc": "Like Steve Swagger.", + "achievement.oc.networkCard": "现在我们在聊天了!", + "achievement.oc.networkCard.desc": "Keep in touch with those distant relatives via transitive relations.", + "achievement.oc.openOS": "启动", + "achievement.oc.openOS.desc": "One OS to - wait, I used that one already? Dang.", + "achievement.oc.powerDistributor": "分享即关怀", + "achievement.oc.powerDistributor.desc": "当你在平衡供电时需要帮助的时候。", + "achievement.oc.rack": "Dat Rack", + "achievement.oc.rack.desc": "我不知道你想歪到哪里去了,我已经说得很明白了,就是服务器架。", + "achievement.oc.raid": "LFG", + "achievement.oc.raid.desc": "Heroic plzkthx.", + "achievement.oc.ram": "随机存取存储器", + "achievement.oc.ram.desc": "恭喜,你的操作完全正确。", + "achievement.oc.redstoneCard": "联系", + "achievement.oc.redstoneCard.desc": "模拟信号时间到。", + "achievement.oc.redstoneIO": "The Outsider", + "achievement.oc.redstoneIO.desc": "将红石信号传播到你需要的地方!", + "achievement.oc.robot": "Beep Boop", + "achievement.oc.robot.desc": "灭绝!", + "achievement.oc.screen": "试过反复开关这屏幕没?", + "achievement.oc.screen.desc": "真没有。毕竟红石信号就可以开关这屏幕了。", + "achievement.oc.server": "专用", + "achievement.oc.server.desc": "云服务,现已正式推出。", + "achievement.oc.switch": "复杂拓扑学", + "achievement.oc.switch.desc": "远离易碎货物,因为包裹可能会掉下来。", + "achievement.oc.tablet": "不要吸入", + "achievement.oc.tablet.desc": "同时请远离儿童,以避免不必要的信用卡过度透支。", + "achievement.oc.transistor": "Tell Red I said \"Hi.\"", + "achievement.oc.transistor.desc": "制作一个晶体管然后让它工作。然后听录音带。不用谢我。", + "achievement.oc.wirelessNetworkCard": "信号", + "achievement.oc.wirelessNetworkCard.desc": "是时候让数据包踏遍每一个角落了。", + "death.attack.oc.nanomachinesOverload.1": "%s 过于贪婪。", + "death.attack.oc.nanomachinesOverload.2": "%s 神经断裂。", + "death.attack.oc.nanomachinesOverload.3": "%s 的纳米机器失控暴走了。", + "death.attack.oc.nanomachinesHungry.1": "%s 被纳米机器吃掉了。", + "death.attack.oc.nanomachinesHungry.2": "%s 忘记喂饱纳米机器了。", + "death.attack.oc.nanomachinesHungry.3": "%s 已被分解吸收了。", + "nei.options.inventory.oredict": "显示矿物词典名", + "nei.options.inventory.oredict.true": "是", + "nei.options.inventory.oredict.false": "否", + "nei.usage.oc.Manual": "打开手册", + "option.oc.address": "地址", + "option.oc.componentName": "组件名", + "option.oc.energy": "能量" +} diff --git a/src/main/resources/assets/opencomputers/lang/zh_tw.json b/src/main/resources/assets/opencomputers/lang/zh_tw.json new file mode 100644 index 0000000000..16a3469ad9 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lang/zh_tw.json @@ -0,0 +1,444 @@ +{ + "tile.oc.accesspoint": "§c橋接器§7", + "tile.oc.adapter": "連接器", + "tile.oc.assembler": "機器組裝台", + "tile.oc.cable": "線纜", + "tile.oc.capacitor": "電容", + "tile.oc.case1": "基礎電腦機殼", + "tile.oc.case2": "高級電腦機殼", + "tile.oc.case3": "超級電腦機殼", + "tile.oc.casecreative": "電腦機殼(創造模式)", + "tile.oc.chameliumblock": "變色凝膠磚", + "tile.oc.charger": "充電器", + "tile.oc.disassembler": "拆解機", + "tile.oc.diskdrive": "磁碟機", + "tile.oc.endstone": "終界石", + "tile.oc.geolyzer": "硬度分析機", + "tile.oc.hologram1": "全息投影機 (1級)", + "tile.oc.hologram2": "全息投影機 (2級)", + "tile.oc.keyboard": "鍵盤", + "tile.oc.microcontroller": "微型控制器", + "tile.oc.motionsensor": "動作感應器", + "tile.oc.netsplitter": "網路路由器", + "tile.oc.powerconverter": "能源轉換器", + "tile.oc.powerdistributor": "能源分配器", + "tile.oc.print": "3D 列印", + "tile.oc.printer": "3D 列印機", + "tile.oc.raid": "磁碟陣列機(NAS)", + "tile.oc.redstone": "紅石I/O", + "tile.oc.relay": "中繼器", + "tile.oc.robot": "機器人", + "tile.oc.robotafterimage": "機器人", + "tile.oc.screen1": "黑白電腦顯示器", + "tile.oc.screen2": "彩色電腦顯示器", + "tile.oc.screen3": "高畫質電腦顯示器", + "tile.oc.rack": "伺服器機架", + "tile.oc.switch": "路由器", + "tile.oc.transposer": "差轉機", + "tile.oc.waypoint": "路點", + "item.oc.abstractbusCard": "抽象的介面卡", + "item.oc.acid": "蝕刻藥水", + "item.oc.alu": "算邏運算單元(ALU)", + "item.oc.analyzer": "分析器", + "item.oc.apu0": "加速處理單元 (APU) (1級)", + "item.oc.apu1": "加速處理單元 (APU) (2級)", + "item.oc.apu2": "加速處理單元 (APU) (創造模式)", + "item.oc.arrowkeys": "方向鍵", + "item.oc.buttongroup": "按鈕組", + "item.oc.cardbase": "主板", + "item.oc.chamelium": "變色凝膠", + "item.oc.circuitboard": "電路板", + "item.oc.componentbus0": "基礎排線", + "item.oc.componentbus1": "高級排線", + "item.oc.componentbus2": "超級排線", + "item.oc.controlunit": "控制單元 (CU)", + "item.oc.cpu0": "中央處理器 (CPU) (1級)", + "item.oc.cpu1": "中央處理器 (CPU) (2級)", + "item.oc.cpu2": "中央處理器 (CPU) (3級)", + "item.oc.cuttingwire": "切割線", + "item.oc.datacard0": "資料卡 (1級)", + "item.oc.datacard1": "資料卡 (2級)", + "item.oc.datacard2": "資料卡 (3級)", + "item.oc.debugcard": "除錯卡", + "item.oc.debugger": "網路除錯卡", + "item.oc.disk": "磁碟", + "item.oc.drone": "無人機", + "item.oc.dronecase0": "無人機外殼 (1級)", + "item.oc.dronecase1": "無人機外殼 (2級)", + "item.oc.dronecase3": "無人機外殼 (創造模式)", + "item.oc.eeprom": "電子抹除式可複寫唯讀記憶體(EEPROM)", + "item.oc.floppydisk": "磁碟片", + "item.oc.graphicscard0": "顯示卡", + "item.oc.graphicscard1": "彩色顯示卡", + "item.oc.graphicscard2": "高畫質顯示卡", + "item.oc.harddiskdrive0": "硬碟機 (1級)", + "item.oc.harddiskdrive1": "硬碟機 (2級)", + "item.oc.harddiskdrive2": "硬碟機 (3級)", + "item.oc.hoverboots": "懸停靴", + "item.oc.inkcartridge": "墨水匣", + "item.oc.inkcartridgeempty": "墨水匣(空)", + "item.oc.internetcard": "上網卡", + "item.oc.interweb": "因特網", + "item.oc.ironnugget": "鐵粒", + "item.oc.linkedcard": "連結卡", + "item.oc.manual": "開放式電腦手冊", + "item.oc.memory0": "記憶卡 (1級)", + "item.oc.memory1": "記憶卡 (1.5級)", + "item.oc.memory2": "記憶卡 (2級)", + "item.oc.memory3": "記憶卡 (2.5級)", + "item.oc.memory4": "記憶卡 (3級)", + "item.oc.memory5": "記憶卡 (3.5級)", + "item.oc.microchip0": "微晶片 (1級)", + "item.oc.microchip1": "微晶片 (2級)", + "item.oc.microchip2": "微晶片 (3級)", + "item.oc.microcontrollercase0": "微控制器外殼 (Tier 1)", + "item.oc.microcontrollercase1": "微控制器外殼 (Tier 2)", + "item.oc.microcontrollercase3": "微控制器外殼 (Creative)", + "item.oc.nanomachines": "納米機器", + "item.oc.networkcard": "網路卡", + "item.oc.numpad": "數字鍵盤", + "item.oc.present": "一個小東西...", + "item.oc.printedcircuitboard": "印刷電路板(PCB)", + "item.oc.rawcircuitboard": "電路板材料", + "item.oc.redstonecard0": "紅石卡 (1級)", + "item.oc.redstonecard1": "紅石卡 (2級)", + "item.oc.server0": "伺服器 (1級)", + "item.oc.server1": "伺服器 (2級)", + "item.oc.server2": "伺服器 (3級)", + "item.oc.server3": "伺服器 (創造模式)", + "item.oc.tablet": "平板電腦", + "item.oc.tabletcase0": "平板電腦保護套 (1級)", + "item.oc.tabletcase1": "平板電腦保護套 (2級)", + "item.oc.tabletcase3": "平板電腦保護套 (創造模式)", + "item.oc.terminal": "遠端終端機", + "item.oc.texturepicker": "紋理選擇器", + "item.oc.transistor": "電晶體", + "item.oc.upgradeangel": "天使升級", + "item.oc.upgradebattery0": "電池升級 (1級)", + "item.oc.upgradebattery1": "電池升級 (2級)", + "item.oc.upgradebattery2": "電池升級 (3級)", + "item.oc.upgradechunkloader": "區塊載入器升級", + "item.oc.upgradecontainercard0": "卡片集裝箱 (1級)", + "item.oc.upgradecontainercard1": "卡片集裝箱 (2級)", + "item.oc.upgradecontainercard2": "卡片集裝箱 (3級)", + "item.oc.upgradecontainerupgrade0": "集裝箱升級 (1級)", + "item.oc.upgradecontainerupgrade1": "集裝箱升級 (2級)", + "item.oc.upgradecontainerupgrade2": "集裝箱升級 (3級)", + "item.oc.upgradecrafting": "合成升級", + "item.oc.upgradedatabase0": "資料庫升級 (1級)", + "item.oc.upgradedatabase1": "資料庫升級 (2級)", + "item.oc.upgradedatabase2": "資料庫升級 (3級)", + "item.oc.upgradeexperience": "經驗升級", + "item.oc.upgradegenerator": "發電機升級", + "item.oc.upgradehover0": "懸停升級 (1級)", + "item.oc.upgradehover1": "懸停升級 (2級)", + "item.oc.upgradeinventory": "物品欄升級", + "item.oc.upgradeinventorycontroller": "物品控制器升級", + "item.oc.upgradeleash": "皮帶升級", + "item.oc.upgradenavigation": "導航升級", + "item.oc.upgradepiston": "活塞升級", + "item.oc.upgradesign": "告示牌 I/O 升級", + "item.oc.upgradesolargenerator": "太陽能發電升級", + "item.oc.upgradetank": "水箱升級", + "item.oc.upgradetankcontroller": "高級水箱升級", + "item.oc.upgradetractorbeam": "牽引光束升級", + "item.oc.wirelessnetworkcard0": "無線網卡", + "item.oc.wirelessnetworkcard1": "無線網卡", + "item.oc.worldsensorcard": "世界傳感器卡", + "item.oc.wrench": "螺絲刀扳手", + "itemGroup.OpenComputers": "OpenComputers", + "entity.oc.drone": "無人機", + "oc:gui.Analyzer.Address": "§6位址§f: %s", + "oc:gui.Analyzer.AddressCopied": "位址複製到剪貼簿.", + "oc:gui.Analyzer.ChargerSpeed": "§6充電速度§f: %s", + "oc:gui.Analyzer.ComponentName": "§6設備元件名稱§f: %s", + "oc:gui.Analyzer.Components": "§6連接元件的數量§f: %s", + "oc:gui.Analyzer.CopyToClipboard": "點擊複製到剪貼簿。", + "oc:gui.Analyzer.LastError": "§6上一個錯誤§f: %s", + "oc:gui.Analyzer.RobotName": "§6名字§f: %s", + "oc:gui.Analyzer.RobotOwner": "§6持有者§f: %s", + "oc:gui.Analyzer.RobotXp": "§6經驗值§f: %s", + "oc:gui.Analyzer.StoredEnergy": "§6儲存能量§f: %s", + "oc:gui.Analyzer.TotalEnergy": "§6總儲存能量§f: %s", + "oc:gui.Analyzer.Users": "§6使用者§f: %s", + "oc:gui.Analyzer.WirelessStrength": "§6信號強度§f: %s", + "oc:gui.Assembler.Collect": "收集機器人", + "oc:gui.Assembler.Complexity": "複雜性: %s/%s", + "oc:gui.Assembler.InsertCase": "裝入電腦機殼(CASE)", + "oc:gui.Assembler.InsertCPU": "裝入中央處理器(CPU)", + "oc:gui.Assembler.InsertRAM": "裝入一些記憶體(RAM)", + "oc:gui.Assembler.Progress": "進度: %s%% (%s)", + "oc:gui.Assembler.Run": "開始組裝機器人", + "oc:gui.Assembler.Warnings": "§e警告§7: 缺少某些建議的零組件", + "oc:gui.Assembler.Warning.GraphicsCard": "顯示卡", + "oc:gui.Assembler.Warning.Inventory": "物品欄升級組件", + "oc:gui.Assembler.Warning.Keyboard": "鍵盤", + "oc:gui.Assembler.Warning.OS": "開機(作業系統) 中等", + "oc:gui.Assembler.Warning.Screen": "螢幕", + "oc:gui.Assembler.Warnings": "§e警告§7: 缺少建議的零組件", + "oc:gui.Chat.NewVersion": "有新版本可用: %s", + "oc:gui.Chat.TextureName": "§7紋理名稱是 §a%s§f.", + "oc:gui.Chat.WarningClassTransformer": "There were §cerrors§f running the class transformer. Please report this, together with your (full!) FML §alatest.log§f/§afml-server-latest.log§f logfile, thank you!", + "oc:gui.Chat.WarningFingerprint": "§c警告§f - 指紋不符!預期 '§a%s§f' 但得到 '§e%s§f'. Unless you are a modder and are running the deobfuscated version of the mod, it is §lstrongly§f recommended to redownload OpenComputers, because the JAR you are using may have been tampered with.", + "oc:gui.Chat.WarningLink": "無法打開鏈接: %s", + "oc:gui.Chat.WarningLuaFallback": "本機 LUA 函式庫無法使用,電腦將無法維持狀態,他會重新啟動並且載入區塊", + "oc:gui.Chat.WarningProjectRed": "你正在使用的 Project: Red 模組與 OpenComputers 不相容. 請嘗試更新 Project: Red.", + "oc:gui.Chat.WarningRecipes": "There were errors loading one or more recipes. Some items may be uncraftable. Please check your log file for more information.", + "oc:gui.Drive.Managed": "受管", + "oc:gui.Drive.Unmanaged": "非受管", + "oc:gui.Drive.Warning": "§l警告§r: 切換模式會導致目前儲存在硬碟上的所有資料遺失!", + "oc:gui.Error.ComponentOverflow": "太多的元件連接到電腦上了", + "oc:gui.Error.InternalError": "內部錯誤,請查看日誌文件。這可能是一個錯誤。", + "oc:gui.Error.NoCPU": "電腦內沒有安裝中央處理器(CPU).", + "oc:gui.Error.NoEnergy": "沒有能源", + "oc:gui.Error.NoRAM": "電腦內沒有安裝記憶卡", + "oc:gui.Error.OutOfMemory": "記憶體不足", + "oc:gui.Manual.Blocks": "開放式電腦方塊", + "oc:gui.Manual.Home": "首頁", + "oc:gui.Manual.Items": "開放式電腦物品", + "oc:gui.Manual.Warning.BlockMissing": "方塊不存在", + "oc:gui.Manual.Warning.ImageMissing": "沒有找到圖片", + "oc:gui.Manual.Warning.ItemMissing": "物品不存在", + "oc:gui.Manual.Warning.OreDictMissing": "礦物字典不存在", + "oc:gui.Raid.Warning": "§4放入的硬碟機會清除硬碟資料.\n移除硬碟機會刪除磁碟陣列機(NAS)資料.", + "oc:gui.Robot.Power": "能量", + "oc:gui.Robot.TurnOff": "關閉", + "oc:gui.Robot.TurnOn": "開啟", + "oc:gui.Rack.None": "無", + "oc:gui.Rack.Back": "背面", + "oc:gui.Rack.Bottom": "底部", + "oc:gui.Rack.Left": "左", + "oc:gui.Rack.Right": "右", + "oc:gui.Rack.Top": "上", + "oc:gui.Switch.TransferRate": "週期率", + "oc:gui.Switch.PacketsPerCycle": "封包 / 週期", + "oc:gui.Switch.QueueSize": "隊列大小", + "oc:gui.Terminal.InvalidKey": "按鍵無效時,最有可能另一端已經綁定到伺服器。", + "oc:gui.Terminal.OutOfRange": "沒訊號.", + "oc:container.accesspoint": "橋接器", + "oc:container.adapter": "連接器", + "oc:container.case": "電腦", + "oc:container.charger": "充電器", + "oc:container.disassembler": "拆解機", + "oc:container.diskdrive": "硬碟機", + "oc:container.printer": "印表機", + "oc:container.raid": "磁碟陣列機(NAS)", + "oc:container.relay": "中繼器", + "oc:container.server": "伺服器", + "oc:container.rack": "伺服器機架", + "oc:container.switch": "路由器", + "oc:container.tabletwrapper": "平板電腦", + "key.opencomputers.clipboardPaste": "貼上剪貼簿", + "key.opencomputers.materialCosts": "顯示材料成本", + "oc:tooltip.accesspoint": "就像一個切換器,但它會接收無線封包並且轉換無線的封包變成有線的封包.", + "oc:tooltip.abstractbuscard": "允許與 §fStargateTech 2§7 抽象卡傳送與接收 LIP 封包.", + "oc:tooltip.acid": "一種有毒的假液相物質,通常只有某些海盜會使用它們.\n它的腐蝕特性令它非常完美地適用于蝕刻電路板的材料.", + "oc:tooltip.adapter": "用于控制非電腦組件的方塊,\n比如原版或者來自其他模組的方塊.", + "oc:tooltip.alu": "用來做算邏運算以免你親自代勞,\n它更勝任這份差事.", + "oc:tooltip.analyzer": "用于顯示方塊信息,比如它們的§f地址§7和§f組件名稱§7.\n如果計算機未能正常關閉它也會顯示使得計算機崩潰的報錯.", + "oc:tooltip.apu": "這是 CPU 組成 GPU (或 IGP)的一個處理器, 如果你需要額外的卡片插槽,他可以讓你減少一片顯示卡.\n支援的零組件: §f%s§7\n最大分辨率: §f%sx%s§7\n最大顏色深度: §f%s§7\n運作/tick: §f%s§7", + "oc:tooltip.assembler": "機器組裝台可以從不同的電腦零組件來組裝一台機器人。", + "oc:tooltip.cable": "連接方塊的廉價選擇.", + "oc:tooltip.capacitor": "儲能以備他用.\n能夠非常快速地充電放電.", + "oc:tooltip.cardbase": "正如其名,它是用來安裝其他擴展卡的基本卡板.", + "oc:tooltip.case": "計算機電腦機殼是構建計算機的基本方塊,\n也是各種§f介面卡§7,§f記憶體§7以及§f硬碟§7的外殼.\n格子: §f%s§7", + "oc:tooltip.chamelium": "3D列印的原料. 不可吞食: 會導致失明與臨時性身體消失", + "oc:tooltip.chameliumblock": "乾淨清潔. 方便用於3D列印, 只是一個純色的乾淨方塊, 彩色方塊可以讓你發揮創意", + "oc:tooltip.charger": "將電容器的能量傳輸給相鄰機器人.\n傳輸效率取決于輸入的§f紅石信號§7強度,無信號意味著不給機器人充電,而最強信號則意味著全速給機器人充電.", + "oc:tooltip.circuitboard": "現在我們已經取得一些進展.\n可以通過蝕刻來得到印制板.", + "oc:tooltip.controlunit": "用來控制...控制東西...的單元.\n你需要這玩意兒來做CPU.所以反正啦,這個非常重要.", + "oc:tooltip.componentbus": "這個擴充套件能讓伺服器同時與更多組件通訊, 工作原理類似CPU.\n支援的組件: §f%s§7.", + "oc:tooltip.cpu": "所有計算機最核心的組件,它的時鐘頻率有點不可靠,\n但是你考慮到它是靠便攜日晷來運行的你還能指望啥呢?", + "oc:tooltip.cpu.architecture": "架構: §f%s§7", + "oc:tooltip.cuttingwire": "用于將粘土塊切割成電路板的形狀.\n使用一次就會壞掉,這可能使得成為歷來最低效的工具.", + "oc:tooltip.datacard0": "提供了一些先進的演算法,如散列處理以及 deflate/inflate.", + "oc:tooltip.datacard1": "提供了一些先進的演算法,如散列處理, AES 加密 以及 deflate/inflate.", + "oc:tooltip.datacard2": "提供了一些先進的演算法,如散列處理, AES 加密, elliptic curve cryptography and deflate/inflate.", + "oc:tooltip.debugcard": "創造模式物品, 它能讓你更簡易的操控世界來進行測試. 請自己承擔它帶來的危險.", + "oc:tooltip.debugger": "可以使用輸出錯誤訊息到 OC's 網路. 只能使用在開發模式.", + "oc:tooltip.disassembler": "拆解還原成它原來的零組件 §l警告§7: 拆解物品過程中 %s%% 有可能破壞掉這些零組件!", + "oc:tooltip.disk": "用於制造持久存儲設備的原始媒介材料.", + "oc:tooltip.diskdrive.cc": "已經§a支持§7使用另一個電腦模組(ComputerCraft)的軟碟.", + "oc:tooltip.diskdrive": "用來讀寫軟碟.", + "oc:tooltip.diskusage": "磁碟使用量: %s/%s Byte", + "oc:tooltip.diskmodemanaged": "模式: 受管", + "oc:tooltip.diskmodeunmanaged": "模式: 非受管", + "oc:tooltip.drone": "無人機重量輕,速度快的偵察部隊,擁有有限的載貨空間。", + "oc:tooltip.dronecase": "這個外殼是用來建立無人機的組裝外殼。它有足夠的空間用於少量組件,並終界石供電懸浮。", + "oc:tooltip.eeprom": "非常小的程式化儲存裝置,可裝入電腦 BIOS 用來開機.", + "oc:tooltip.fakeendstone": "幾乎一樣好真實的東西,甚至模仿其floatiness!", + "oc:tooltip.geolyzer": "允許掃描周邊地區的方塊硬度,這個訊息可用於產生區域的全息圖,或用來檢測礦石是非常有用的.", + "oc:tooltip.graphicscard": "用來改變顯示器顯示內容.\n最高分辨率: §f%sx%s§7\n最大色深: §f%s§7", + "oc:tooltip.hoverboots": "跳得更高, 跌幅更深, 走得更快. 這是一個全新專利的 懸停靴 (TM).", + "oc:tooltip.inkcartridge": "用於填充墨水的3D打印機。很神奇的原理,不必保留在印表機中。", + "oc:tooltip.inkcartridgeempty": "這個墨盒已經被吸乾。用染料填充它。或者把它扔掉。看看你是否在乎。", + "oc:tooltip.internetcard": "這個介面卡允許你發出 HTTP要求到真實的 TCP sockets.", + "oc:tooltip.interweb": "恭喜,你贏取了 (1) 因特網,你可以使用網路卡連接它,小心,不要餵食巨魔.", + "oc:tooltip.ironnugget": "顆粒狀的鐵,所以叫鐵粒啦,蠢蠢的感覺...", + "oc:tooltip.keyboard": "可以連接顯示器,能夠輸入顯示文本.", + "oc:tooltip.hologram0": "可以透過電腦進行控制以顯示任意像素體積的結構體.\n解析度: §f48x32x48§7\n最大縮放: §f3x§7\n色深: §f單色§7", + "oc:tooltip.hologram1": "可以透過電腦進行控制以顯示任意像素體積的結構體.\n解析度: §f48x32x48§7\n最大縮放: §f4x§7\n色深: §f三色§7", + "oc:tooltip.linkedcard": "這些都是製作成對的,而且只能與它的合作卡通訊,然而,它可以在任何距離,甚至是誇世界溝通,但是發送訊息的消耗的能量非常高.", + "oc:tooltip.linkedcard_channel": "§8頻道: %s§7", + "oc:tooltip.manual": "所有你需要知道開放式電腦模組的訊息都在裡面.而且他的需求非常便宜... §o請按 R 繼續§7.", + "oc:tooltip.materialcosts": "按著 [§f%s§7] 顯示材料成本.", + "oc:tooltip.materials": "需求材料:", + "oc:tooltip.memory": "電腦運行必備.\n記憶體越大,你就可以運行越復雜的程序.", + "oc:tooltip.microchip": "通常也管這種芯片叫集成電路.\n我也不知道為啥能和紅石一起運行,但事實如此啊.", + "oc:tooltip.microcontroller": "微控制器是一部小型電腦. 它的目的是在處理非常具體的任務, 只能執行儲存在 EEPROM 的單一獨立程式.\n§c無法連結外部零組件.§7", + "oc:tooltip.microcontrollercase": "微控制器的基本組件. 將其放入組裝機裡添加其他的零組件", + "oc:tooltip.motionsensor": "可以檢測到附近活物的移動,需要在視線內不能有阻擋物.", + "oc:tooltip.nanomachines": "如果你敢,插入控制單元與一組奈米機器", + "oc:tooltip.networkcard": "允許通過其他方塊(比如線纜)相連的遠程計算機能夠向彼此發送信息進行交互.", + "oc:tooltip.poweracceptor": "能源轉換速度: §f%s/t§7", + "oc:tooltip.powerconverter.BuildCraft": "§f建築模組minecraft焦耳(BC-MJ)§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Factorization": "§f因式分解 (Charge)§7: §a%s:%s§7", + "oc:tooltip.powerconverter.IndustrialCraft2": "§f工業時代 EU(IC²-EU)§7: §a%s:%s§7", + "oc:tooltip.powerconverter.Mekanism": "§f通用機器焦耳(Joules)§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ThermalExpansion": "§f熱能擴展RF(TE-RF)§7: §a%s:%s§7", + "oc:tooltip.powerconverter.ResonantEngine": "§f諧振引擎庫侖§7: §a%s:%s§7", + "oc:tooltip.powerconverter": "將其他模組的能量轉化為本模組的內部能源形式.轉換率:", + "oc:tooltip.powerdistributor": "在不同網絡中分配能量.\n用來通過包含多個理論上獨立的子網絡的轉換器在系統中共享能量時很實用.", + "oc:tooltip.present": "... for your troubles. Open this present for a chance to receive some §kphat lewt§7!\n§8Craft OpenComputers items when the time is right for a chance to receive a present.§7", + "oc:tooltip.print.BeaconBase": "§8一盞燈的基座", + "oc:tooltip.print.LightValue": "§8發出的光: %s.", + "oc:tooltip.print.RedstoneLevel": "§8紅石輸出: %s.", + "oc:tooltip.printedcircuitboard": "基本的構建方塊用來裝入擴充卡與記憶體模組", + "oc:tooltip.printer": "允許使用玩家自定義的墨水匣 Chamelium 與 Ink Cartridges. 必須使用電腦來進行配置. 遠離小朋友", + "oc:tooltip.raid": "使用三個硬碟機然後連接電腦成為一個更大容量的資料儲存系統", + "oc:tooltip.printedcircuitboard": "擴展卡,記憶體等的基板.", + "oc:tooltip.rawcircuitboard": "能夠在熔爐或者類似爐子中加工強化成其他材料.", + "oc:tooltip.redstone": "能夠在方塊周圍接收以及發送紅石信號.\n可以被與之相連的計算機控制.基本上就像一個外置紅石卡.", + "oc:tooltip.redstonecard.ProjectRed": "已經§a支持§fProjectRed§7.", + "oc:tooltip.redstonecard.RedLogic": "已經§a支持§7§f紅石邏輯(RedLogic)§7中的紅石系統.", + "oc:tooltip.redstonecard.RedNet": "已經§a支援§7MFR中的§f紅石網絡(RedNet)§7.", + "oc:tooltip.redstonecard.WirelessCBE": "已經§a支援§f無線紅石 (ChickenBones)§7.", + "oc:tooltip.redstonecard.WirelessSV": "已經§a支援§f無線紅石 (SlimeVoid)§7.", + "oc:tooltip.redstonecard": "能夠在計算機和機器人四周接收以及發送紅石信號.", + "oc:tooltip.robot": "和計算機不同,機器人能夠移動并且像玩家那些與世界之中的東西交互.\n然而,它們§o不能§r§7直接與外設進行交互!", + "oc:tooltip.robot_level": "§f等級§7: §a%s§7.", + "oc:tooltip.robot_storedenergy": "§f儲能§7: §a%s§7.", + "oc:tooltip.screen": "由電腦機殼內的顯示卡控制來顯示文字.\n最高分辨率: §f%sx%s§7\n最大色深: §f%s§7", + "oc:tooltip.server": "這是一台伺服器, 他非常棒, 但是他可以使用元件去升級他功能就像電腦一樣. 他可以插入伺服器機架上執行.", + "oc:tooltip.server.Components": "安裝的元件:", + "oc:tooltip.rack": "提供安裝最多達四個伺服器。為每個伺服器提供了一個內置的虛擬鍵盤和螢幕元件,相當於一個遠程終端。", + "oc:tooltip.switch": "允許設備相互連接不同的網絡.\n僅能傳遞網絡信息,通過路由器方式設備并不互相可見.\n例如可以通過這種方式來建立獨立網絡但仍允許其使用網卡通訊.", + "oc:tooltip.tablet": "一台平板電腦, 可以在旅行中使用LUA. 使用潛行按鍵來啟動或是關閉他", + "oc:tooltip.tabletcase": "平板電腦的機殼,將它放置在機器組裝台內製作一台平板電腦", + "oc:tooltip.terminal": "允許遠程控制伺服器,只要你在它的範圍內。就像一個隨身型螢幕和鍵盤。按住Shift鍵並滑鼠右鍵單擊某個服務器的服務器機架終端綁定它。", + "oc:tooltip.texturepicker": "可以工具允許顯示方塊該面向的紋理描述, 主要用於3D印表機. 完全沒有紋理名字,沒了!", + "oc:tooltip.tier": "§8等級 %s", + "oc:tooltip.netsplitter": "作為一個動態連接器。每邊的連接可以通過用扳手擊中它進行切換。所有邊的連接可以通過應用紅石信號反轉。", + "oc:tooltip.toolong": "按住潛行鍵([§f%s§7])以查看詳細提示信息.", + "oc:tooltip.transistor": "在多數其他計算機的零件中都很基礎的元件.\n引腳有點彎了,但還能用。", + "oc:tooltip.transposer": "允許相鄰的箱子與液體容器之間的物品液體transferral", + "oc:tooltip.upgradeangel": "讓機器人能夠憑空放置方塊在任何地方,即使沒有參考點可以依附放置。", + "oc:tooltip.upgradebattery": "增加機器人可儲存的能量,讓它可以工作更長的時間不需要補充能量.\n容量: §f%s§7", + "oc:tooltip.upgradechunkloader": "如果機器人在森林中移動,周圍沒有其他玩家,它真的會動嗎? 這個升級組件可以確保它持續地在作用中,它使區塊持續在載入狀態,但會不斷消耗能量,維持它。", + "oc:tooltip.upgradecontainercard": "這個集裝箱升級組件允許動態裝配機器人內的某個插卡.\n最大等級: §f%s§7", + "oc:tooltip.upgradecontainerupgrade": "這個集裝箱升級組件允許動態裝配機器人內的某個升級組件\n最大等級: §f%s§7", + "oc:tooltip.upgradecrafting": "使得機器人能夠將其物品欄的左上區域作為合成網格來制做物品.\n物品欄內物品擺放必須與工作臺中一致.", + "oc:tooltip.upgradedatabase": "這個升級允許儲存用於檢索與其他組件的堆疊訊息.\n支持的條目: §f%s§7", + "oc:tooltip.upgradeexperience": "這個升級組件,能夠讓機器人執行各種操作,累積更多的經驗,然後它會獲得更多的能量,更多的儲存空間,速度更快,它收割更有效率,也能使用工具。", + "oc:tooltip.upgradegenerator": "用來不斷地消耗燃料發電,燃燒物品并基于它們的燃燒值隨著時間推移產生電力.\n§f效率§7: §a%s%%§7。", + "oc:tooltip.upgradehover": "可以升級可以讓機器人飛離地面更高,而且不用爬牆.\n最大高度: §f%s§7", + "oc:tooltip.upgradeinventory": "這個升級組件提供機器人一個物品放置的空間,沒有這個升級組件,機器人將不能再內部儲存任何物品。", + "oc:tooltip.upgradeinventoryController": "這個升級組件可以讓機器人更好的控制如何與外部互動物品,並且允許他交換或是裝備物品欄內的工具。", + "oc:tooltip.upgradeleash": "允許一些設備,如無人機, 來綁定 Isaa- excuse me... *chatter* My apologies. 我只是被告知這其實是用來綁住多種動物在木樁上.", + "oc:tooltip.upgradenavigation": "可以用來確定機器人的位置和方向。該位置是相對於被用來製作這個升級地圖的中心。", + "oc:tooltip.upgradepiston": "這個升級十分有用. 它能讓機器人像活塞那樣移動方塊, 但 §l不能§7 移動實體.", + "oc:tooltip.upgradesign": "允許讀取文字與寫入文字到告示牌", + "oc:tooltip.upgradesolarGenerator": "在移動中可以從陽光獲取能量. 機器人上方必須保持無遮蔽狀態才能. 產生能量 %s%% 速度的能量給引擎。", + "oc:tooltip.upgradetank": "為你的機器人裝上一個可存儲流體的水箱. 如果沒有升級此功能, 你的機器人將無法在內部存儲流體.", + "oc:tooltip.upgradetankcontroller": "這個升級能讓你的機器人與外界水箱交互, 向其傳輸流體.", + "oc:tooltip.upgradetractorbeam": "裝備機器人具有非常先進的技術,綽號\"物品磁鐵\"。它能夠拾取三個方塊內的任何地方。", + "oc:tooltip.waypoint": "提供一個參考點到與導航設備的升級。", + "oc:tooltip.wirelessnetworkcard": "允許在發送正常信息外無線發送網絡信息.\n請確保已設置好§f信號強度§7否則不會發出無線數據包。", + "oc:tooltip.worldsensorcard": "允許讀取世界訊息,比如重力,以及是否在大氣下,傳回結果.", + "oc:tooltip.wrench": "螺絲刀和扳手的混合體,這個工具是簡單易學,但很難掌握。", + "achievement.oc.adapter": "插上寶寶", + "achievement.oc.adapter.desc": "Interact with blocks from other mods and even vanilla Minecraft!", + "achievement.oc.assembler": "美妙", + "achievement.oc.assembler.desc": "Time to take over the world!", + "achievement.oc.cable": "不是一個骯髒的電線", + "achievement.oc.cable.desc": "With patented anti-cable-spaghetti technology.", + "achievement.oc.capacitor": "包括電池", + "achievement.oc.capacitor.desc": "You cannot stop it.", + "achievement.oc.card": "我們接受信用卡", + "achievement.oc.card.desc": "For your convenience. No ulterior motive, promise.", + "achievement.oc.case": "出現故障時", + "achievement.oc.case.desc": "Because cuboid towers are the best.", + "achievement.oc.charger": "好吧,讓我們做到這一點", + "achievement.oc.charger.desc": "Chaaaaaaaaaarg- dang, forgot the redstone signal again.", + "achievement.oc.chip": "所有小事", + "achievement.oc.chip.desc": "Because vacuum tubes are so yesteryear.", + "achievement.oc.cpu": "超頻", + "achievement.oc.cpu.desc": "Time to make good use of those computing cycles.", + "achievement.oc.disassembler": "從頭開始", + "achievement.oc.disassembler.desc": "In case one of your brilliant ideas turns out to be not that brilliant after all.", + "achievement.oc.diskDrive": "環狀交叉路", + "achievement.oc.diskDrive.desc": "Inferior capacity but such delicious sound.", + "achievement.oc.drone": "飛走", + "achievement.oc.drone.desc": "Keep calm and nuke it from orbit.", + "achievement.oc.eeprom": "只能有1", + "achievement.oc.eeprom.desc": "Per computer, that is. For deterministic boot order, you know?", + "achievement.oc.floppy": "在一個RI-磁碟", + "achievement.oc.floppy.desc": "Not to be confused with Flappy.", + "achievement.oc.geolyzer": "腳踏實地", + "achievement.oc.geolyzer.desc": "It has extraordinary qualities.", + "achievement.oc.graphicsCard": "LastGen", + "achievement.oc.graphicsCard.desc": "The way it's meant to be... uh... rendered. Yeah. That.", + "achievement.oc.hdd": "熱狗經銷商", + "achievement.oc.hdd.desc": "No wait, that's not what that meant. Hang on, almost got it...", + "achievement.oc.hologram": "下一個維度", + "achievement.oc.hologram.desc": "Because 2D is boring. Or is it?", + "achievement.oc.keyboard": "DirtCatcher3000", + "achievement.oc.keyboard.desc": "It is highly recommended to resist the urge to flip them around and shake them.", + "achievement.oc.microcontroller": "小妹妹", + "achievement.oc.microcontroller.desc": "The small sibling of computers.", + "achievement.oc.motionSensor": "能動", + "achievement.oc.motionSensor.desc": "Like Steve Swagger.", + "achievement.oc.networkCard": "現在我們談論!", + "achievement.oc.networkCard.desc": "Keep in touch with those distant relatives via transitive relations.", + "achievement.oc.openOS": "開機", + "achievement.oc.openOS.desc": "One OS to - wait, I used that one already? Dang.", + "achievement.oc.powerDistributor": "共享是關懷", + "achievement.oc.powerDistributor.desc": "When you need some help balancing all that power.", + "achievement.oc.rack": "Dat Rack", + "achievement.oc.rack.desc": "I don't know what you're thinking of, I clearly meant the server rack.", + "achievement.oc.raid": "LFG", + "achievement.oc.raid.desc": "Heroic plzkthx.", + "achievement.oc.ram": "隨機存取存儲器", + "achievement.oc.ram.desc": "Congratulations, you're Doin' It Right.", + "achievement.oc.redstoneCard": "聯繫", + "achievement.oc.redstoneCard.desc": "Time to go analog.", + "achievement.oc.redstoneIO": "局外人", + "achievement.oc.redstoneIO.desc": "Taking redstone signals where you want them.", + "achievement.oc.robot": "嗶布普", + "achievement.oc.robot.desc": "EXTERMINATE!", + "achievement.oc.screen": "Have you tried turning it off and on again?", + "achievement.oc.screen.desc": "No seriously. A redstone pulse can toggle a screen's power, after all.", + "achievement.oc.server": "專用", + "achievement.oc.server.desc": "雲服務,我們來了。", + "achievement.oc.switch": "複雜的拓撲", + "achievement.oc.switch.desc": "避免易碎物品因遺失資料的可能性。", + "achievement.oc.tablet": "不要嚥下", + "achievement.oc.tablet.desc": "Also keep away from small children to avoid unexpected overdrawing of your credit card.", + "achievement.oc.transistor": "告訴紅石說:“你好。”", + "achievement.oc.transistor.desc": "Create a Transistor to get started. Then listen to the soundtrack. No need to thank me.", + "achievement.oc.wirelessNetworkCard": "信號", + "achievement.oc.wirelessNetworkCard.desc": "Time to go where no packet has gone before.", + "death.attack.oc.nanomachinesOverload.1": "%s 獲得貪婪稱號。", + "death.attack.oc.nanomachinesOverload.2": "%s 神經衰弱。", + "death.attack.oc.nanomachinesOverload.3": "奈米機器 %s 失去控制", + "death.attack.oc.nanomachinesHungry.1": "%s 被奈米機器吃掉", + "death.attack.oc.nanomachinesHungry.2": "%s 沒有定時餵食奈米機器", + "death.attack.oc.nanomachinesHungry.3": "%s 已被消化。", + "nei.options.inventory.oredict": "顯示礦物字典名稱", + "nei.options.inventory.oredict.true": "真", + "nei.options.inventory.oredict.false": "假", + "nei.usage.oc.Manual": "打開手冊", + "option.oc.address": "位址", + "option.oc.componentName": "組件名稱", + "option.oc.energy": "能源" +} diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.32.arm.so b/src/main/resources/assets/opencomputers/lib/lua52/native.32.arm.so deleted file mode 100644 index e21c6aa412..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.32.arm.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.32.bsd.so b/src/main/resources/assets/opencomputers/lib/lua52/native.32.bsd.so deleted file mode 100644 index df03aa6683..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.32.bsd.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.32.dll b/src/main/resources/assets/opencomputers/lib/lua52/native.32.dll deleted file mode 100644 index db48708e32..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.32.dll and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.32.dylib b/src/main/resources/assets/opencomputers/lib/lua52/native.32.dylib deleted file mode 100644 index 6498ec7e5b..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.32.dylib and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.32.so b/src/main/resources/assets/opencomputers/lib/lua52/native.32.so deleted file mode 100644 index 4c47ab5ee3..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.32.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.64.bsd.so b/src/main/resources/assets/opencomputers/lib/lua52/native.64.bsd.so deleted file mode 100644 index 715dccfaba..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.64.bsd.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.64.dll b/src/main/resources/assets/opencomputers/lib/lua52/native.64.dll deleted file mode 100644 index 0b31407532..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.64.dll and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.64.dylib b/src/main/resources/assets/opencomputers/lib/lua52/native.64.dylib deleted file mode 100644 index b7e7f4a182..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.64.dylib and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua52/native.64.so b/src/main/resources/assets/opencomputers/lib/lua52/native.64.so deleted file mode 100644 index c6fe8fa82b..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua52/native.64.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.32.bsd.so b/src/main/resources/assets/opencomputers/lib/lua53/native.32.bsd.so deleted file mode 100644 index a0d0445993..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.32.bsd.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.32.dll b/src/main/resources/assets/opencomputers/lib/lua53/native.32.dll deleted file mode 100644 index c19c93dc72..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.32.dll and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.32.dylib b/src/main/resources/assets/opencomputers/lib/lua53/native.32.dylib deleted file mode 100644 index c95eaacc80..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.32.dylib and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.32.so b/src/main/resources/assets/opencomputers/lib/lua53/native.32.so deleted file mode 100644 index fc9bb697da..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.32.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.64.bsd.so b/src/main/resources/assets/opencomputers/lib/lua53/native.64.bsd.so deleted file mode 100644 index f0a919079e..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.64.bsd.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.64.dll b/src/main/resources/assets/opencomputers/lib/lua53/native.64.dll deleted file mode 100644 index 34d3a19319..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.64.dll and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.64.dylib b/src/main/resources/assets/opencomputers/lib/lua53/native.64.dylib deleted file mode 100644 index 6702f27498..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.64.dylib and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/lib/lua53/native.64.so b/src/main/resources/assets/opencomputers/lib/lua53/native.64.so deleted file mode 100644 index bbb8306361..0000000000 Binary files a/src/main/resources/assets/opencomputers/lib/lua53/native.64.so and /dev/null differ diff --git a/src/main/resources/assets/opencomputers/loot/loot.properties b/src/main/resources/assets/opencomputers/loot/loot.properties index c1886e02c3..c007863721 100644 --- a/src/main/resources/assets/opencomputers/loot/loot.properties +++ b/src/main/resources/assets/opencomputers/loot/loot.properties @@ -7,18 +7,18 @@ #The color defaults to gray. It must be a dye's ore-dict name. # General purpose. -network=Network (Network Stack):1:dyeLime -plan9k=Plan9k (Operating System):1:dyeRed -irc=OpenIRC (IRC Client):1:dyeLightBlue -openloader=OpenLoader (Boot Loader):1:dyeMagenta -openos=OpenOS (Operating System):0:dyeGreen -oppm=OPPM (Package Manager):0:dyeCyan +network=Network (Network Stack):1:lime +plan9k=Plan9k (Operating System):1:red +irc=OpenIRC (IRC Client):1:light_blue +openloader=OpenLoader (Boot Loader):1:magenta +openos=OpenOS (Operating System):0:green +oppm=OPPM (Package Manager):0:cyan # Robot utilities. -builder=Builder:1:dyeYellow -dig=Digger:2:dyeBrown -maze=Mazer:1:dyeOrange +builder=Builder:1:yellow +dig=Digger:2:brown +maze=Mazer:1:orange # Drivers for components. -data=Data Card Software:0:dyePink -generator=Generator Upgrade Software:0:dyePurple +data=Data Card Software:0:pink +generator=Generator Upgrade Software:0:purple diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/core/lua_shell.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/core/lua_shell.lua index ab07bd6a34..723b04ba8f 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/core/lua_shell.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/core/lua_shell.lua @@ -86,7 +86,7 @@ local read_handler = {hint = function(line, index) return hints end} -io.write("\27[37m".._VERSION .. " Copyright (C) 1994-2017 Lua.org, PUC-Rio\n") +io.write("\27[37m".._VERSION .. " Copyright (C) 1994-2022 Lua.org, PUC-Rio\n") io.write("\27[33mEnter a statement and hit enter to evaluate it.\n") io.write("Prefix an expression with '=' to show its value.\n") io.write("Press Ctrl+D to exit the interpreter.\n\27[37m") diff --git a/src/main/resources/assets/opencomputers/models/item/cable.json b/src/main/resources/assets/opencomputers/models/item/cable.json new file mode 100644 index 0000000000..5485f33463 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/cable.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:block/air" +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyered.json b/src/main/resources/assets/opencomputers/models/item/floppy_black.json similarity index 56% rename from src/main/resources/assets/opencomputers/models/item/floppy_dyered.json rename to src/main/resources/assets/opencomputers/models/item/floppy_black.json index eda33de570..e0820566c1 100644 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyered.json +++ b/src/main/resources/assets/opencomputers/models/item/floppy_black.json @@ -1,6 +1,6 @@ { "parent": "opencomputers:item/flat", "textures": { - "layer0": "opencomputers:items/floppy_dyered" + "layer0": "opencomputers:items/floppy_black" } } diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyeblue.json b/src/main/resources/assets/opencomputers/models/item/floppy_blue.json similarity index 55% rename from src/main/resources/assets/opencomputers/models/item/floppy_dyeblue.json rename to src/main/resources/assets/opencomputers/models/item/floppy_blue.json index 5ab2f34ba8..4da3bf3a04 100644 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyeblue.json +++ b/src/main/resources/assets/opencomputers/models/item/floppy_blue.json @@ -1,6 +1,6 @@ { "parent": "opencomputers:item/flat", "textures": { - "layer0": "opencomputers:items/floppy_dyeblue" + "layer0": "opencomputers:items/floppy_blue" } } diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyelime.json b/src/main/resources/assets/opencomputers/models/item/floppy_brown.json similarity index 55% rename from src/main/resources/assets/opencomputers/models/item/floppy_dyelime.json rename to src/main/resources/assets/opencomputers/models/item/floppy_brown.json index 244c7750a3..ba52c60827 100644 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyelime.json +++ b/src/main/resources/assets/opencomputers/models/item/floppy_brown.json @@ -1,6 +1,6 @@ { "parent": "opencomputers:item/flat", "textures": { - "layer0": "opencomputers:items/floppy_dyelime" + "layer0": "opencomputers:items/floppy_brown" } } diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyecyan.json b/src/main/resources/assets/opencomputers/models/item/floppy_cyan.json similarity index 55% rename from src/main/resources/assets/opencomputers/models/item/floppy_dyecyan.json rename to src/main/resources/assets/opencomputers/models/item/floppy_cyan.json index ef844c9a22..9726f0d09d 100644 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyecyan.json +++ b/src/main/resources/assets/opencomputers/models/item/floppy_cyan.json @@ -1,6 +1,6 @@ { "parent": "opencomputers:item/flat", "textures": { - "layer0": "opencomputers:items/floppy_dyecyan" + "layer0": "opencomputers:items/floppy_cyan" } } diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyegreen.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyegreen.json deleted file mode 100644 index 915a2910e7..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyegreen.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyegreen" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyelightblue.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyelightblue.json deleted file mode 100644 index 635991a8ca..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyelightblue.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyelightblue" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyelightgray.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyelightgray.json deleted file mode 100644 index 3eadf282bb..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyelightgray.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyelightgray" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyemagenta.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyemagenta.json deleted file mode 100644 index be3ff99ca4..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyemagenta.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyemagenta" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyeorange.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyeorange.json deleted file mode 100644 index c2860686cd..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyeorange.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyeorange" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyepink.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyepink.json deleted file mode 100644 index 3ac45505d5..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyepink.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyepink" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyepurple.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyepurple.json deleted file mode 100644 index 4c13535ad3..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyepurple.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyepurple" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyewhite.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyewhite.json deleted file mode 100644 index a8f9b07b06..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyewhite.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyewhite" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyeyellow.json b/src/main/resources/assets/opencomputers/models/item/floppy_dyeyellow.json deleted file mode 100644 index 911ca8afba..0000000000 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyeyellow.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "opencomputers:item/flat", - "textures": { - "layer0": "opencomputers:items/floppy_dyeyellow" - } -} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_gray.json b/src/main/resources/assets/opencomputers/models/item/floppy_gray.json new file mode 100644 index 0000000000..4dd9bd3ce3 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_gray.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_gray" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_green.json b/src/main/resources/assets/opencomputers/models/item/floppy_green.json new file mode 100644 index 0000000000..d7c33188fc --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_green.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_green" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyeblack.json b/src/main/resources/assets/opencomputers/models/item/floppy_light_blue.json similarity index 54% rename from src/main/resources/assets/opencomputers/models/item/floppy_dyeblack.json rename to src/main/resources/assets/opencomputers/models/item/floppy_light_blue.json index 263e9e5997..54f58d4304 100644 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyeblack.json +++ b/src/main/resources/assets/opencomputers/models/item/floppy_light_blue.json @@ -1,6 +1,6 @@ { "parent": "opencomputers:item/flat", "textures": { - "layer0": "opencomputers:items/floppy_dyeblack" + "layer0": "opencomputers:items/floppy_light_blue" } } diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyebrown.json b/src/main/resources/assets/opencomputers/models/item/floppy_light_gray.json similarity index 54% rename from src/main/resources/assets/opencomputers/models/item/floppy_dyebrown.json rename to src/main/resources/assets/opencomputers/models/item/floppy_light_gray.json index c3209a408f..d2c929426f 100644 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyebrown.json +++ b/src/main/resources/assets/opencomputers/models/item/floppy_light_gray.json @@ -1,6 +1,6 @@ { "parent": "opencomputers:item/flat", "textures": { - "layer0": "opencomputers:items/floppy_dyebrown" + "layer0": "opencomputers:items/floppy_light_gray" } } diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_lime.json b/src/main/resources/assets/opencomputers/models/item/floppy_lime.json new file mode 100644 index 0000000000..fe4dac3318 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_lime.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_lime" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_dyegray.json b/src/main/resources/assets/opencomputers/models/item/floppy_magenta.json similarity index 55% rename from src/main/resources/assets/opencomputers/models/item/floppy_dyegray.json rename to src/main/resources/assets/opencomputers/models/item/floppy_magenta.json index f66055135d..1f73c298d8 100644 --- a/src/main/resources/assets/opencomputers/models/item/floppy_dyegray.json +++ b/src/main/resources/assets/opencomputers/models/item/floppy_magenta.json @@ -1,6 +1,6 @@ { "parent": "opencomputers:item/flat", "textures": { - "layer0": "opencomputers:items/floppy_dyegray" + "layer0": "opencomputers:items/floppy_magenta" } } diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_orange.json b/src/main/resources/assets/opencomputers/models/item/floppy_orange.json new file mode 100644 index 0000000000..aa239efa60 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_orange.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_orange" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_pink.json b/src/main/resources/assets/opencomputers/models/item/floppy_pink.json new file mode 100644 index 0000000000..2c9d99b64c --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_pink.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_pink" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_purple.json b/src/main/resources/assets/opencomputers/models/item/floppy_purple.json new file mode 100644 index 0000000000..b036df4d7a --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_purple.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_purple" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_red.json b/src/main/resources/assets/opencomputers/models/item/floppy_red.json new file mode 100644 index 0000000000..b1f4c81056 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_red.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_red" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_white.json b/src/main/resources/assets/opencomputers/models/item/floppy_white.json new file mode 100644 index 0000000000..4fff4486df --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_white.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_white" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/floppy_yellow.json b/src/main/resources/assets/opencomputers/models/item/floppy_yellow.json new file mode 100644 index 0000000000..8013fb314a --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/floppy_yellow.json @@ -0,0 +1,6 @@ +{ + "parent": "opencomputers:item/flat", + "textures": { + "layer0": "opencomputers:items/floppy_yellow" + } +} diff --git a/src/main/resources/assets/opencomputers/models/item/netsplitter.json b/src/main/resources/assets/opencomputers/models/item/netsplitter.json new file mode 100644 index 0000000000..5485f33463 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/netsplitter.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:block/air" +} diff --git a/src/main/resources/assets/opencomputers/models/item/print.json b/src/main/resources/assets/opencomputers/models/item/print.json new file mode 100644 index 0000000000..5485f33463 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/print.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:block/air" +} diff --git a/src/main/resources/assets/opencomputers/models/item/robot.json b/src/main/resources/assets/opencomputers/models/item/robot.json new file mode 100644 index 0000000000..5485f33463 --- /dev/null +++ b/src/main/resources/assets/opencomputers/models/item/robot.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:block/air" +} diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes deleted file mode 100644 index d8da5c9fb8..0000000000 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ /dev/null @@ -1,700 +0,0 @@ -# Do not change this file, it is rewritten each time you start the game. -# Instead, use the user.recipes file to edit recipes by redefining them there. - -analyzer { - input: [[torchRedstoneActive, "", ""] - ["oc:materialTransistor", nuggetGold, ""] - ["oc:materialCircuitBoardPrinted", nuggetGold, ""]] -} -hoverboots { - input: [[iron_nugget, "oc:hoverUpgrade2", iron_nugget] - [leather, "oc:droneCase1", leather] - [iron_nugget, "oc:capacitor", iron_nugget]] -} -manual { - type: shapeless - input: [book, "oc:circuitChip1"] -} -nanomachines { - input: [["oc:chamelium", "oc:wlanCard2", "oc:chamelium"] - ["oc:cpu2", "oc:materialAcid", "oc:ram1"] - ["oc:chamelium", "oc:capacitor", "oc:chamelium"]] -} -texturepicker { - input: [[dyeBlack, dyeRed, dyeGreen] - [dyeBlue, "oc:analyzer", dyePurple] - [dyeYellow, dyeMagenta, dyeWhite]] -} -wrench { - input: [[ingotIron, "", ingotIron] - ["", "oc:circuitChip2", ""], - ["", ingotIron, ""]] -} -lootdisks: [ - { - name: "opencomputers:openos" - type: shapeless - input: ["oc:floppy", "oc:manual"] - }, - { - name: "opencomputers:oppm" - type: shapeless - input: ["oc:floppy", "oc:materialInterweb"] - } -] -luabios { - type: shapeless - input: ["oc:eeprom", "oc:manual"] -} - -dronecase1 { - input: [["oc:stoneEndstone", compass, "oc:stoneEndstone"] - ["oc:circuitChip1", "oc:microcontrollerCase1", "oc:circuitChip1"] - ["oc:stoneEndstone", "oc:componentBus2", "oc:stoneEndstone"]] -} -dronecase2 { - input: [["oc:stoneEndstone", compass, "oc:stoneEndstone"] - ["oc:circuitChip2", "oc:microcontrollerCase2", "oc:circuitChip2"] - ["oc:stoneEndstone", "oc:componentBus3", "oc:stoneEndstone"]] -} -microcontrollercase1 { - input: [[iron_nugget, "oc:circuitChip1", iron_nugget] - [redstone, chest, redstone] - [iron_nugget, "oc:materialCircuitBoardPrinted", iron_nugget]] -} -microcontrollercase2 { - input: [[nuggetGold, "oc:circuitChip3", nuggetGold] - [blockRedstone, chest, blockRedstone] - [nuggetGold, "oc:materialCircuitBoardPrinted", nuggetGold]] -} -terminal { - input: [[iron_nugget, "oc:solarGeneratorUpgrade", iron_nugget] - ["oc:circuitChip3", "oc:screen2", "oc:wlanCard2"] - [iron_nugget, "oc:keyboard", iron_nugget]] -} -tabletcase1 { - input: [[ingotGold, button, ingotGold] - ["oc:componentBus1", "oc:screen2", "oc:circuitChip3"] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -tabletcase2 { - input: [["oc:circuitChip2", button, ingotGold] - ["oc:componentBus3", "oc:screen2", "oc:circuitChip3"] - ["oc:circuitChip2", "oc:materialCircuitBoardPrinted", ingotGold]] -} - -diskdrivemountable { - input: [[obsidian, "oc:circuitChip1", obsidian] - [fenceIron, "oc:diskDrive", fenceIron] - [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] -} -server1 { - input: [[ingotIron, "oc:ram2", ingotIron] - ["oc:circuitChip1", "oc:componentBus1", "oc:circuitChip1"] - [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] -} -server2 { - input: [[ingotGold, "oc:ram4", ingotGold] - ["oc:circuitChip2", "oc:componentBus2", "oc:circuitChip2"] - [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] -} -server3 { - input: [[gemDiamond, "oc:ram6", gemDiamond] - ["oc:circuitChip3", "oc:componentBus3", "oc:circuitChip3"] - [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] -} -terminalserver { - input: [[obsidian, "oc:wlanCard", obsidian] - ["oc:wlanCard", "oc:circuitChip2", "oc:wlanCard2"] - [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] -} - -ram1 { - input: [["oc:circuitChip1", iron_nugget, "oc:circuitChip1"] - ["", "oc:materialCircuitBoardPrinted", ""]] -} -ram2 { - input: [["oc:circuitChip1", "oc:circuitChip2", "oc:circuitChip1"] - ["", "oc:materialCircuitBoardPrinted", ""]] -} -ram3 { - input: [["oc:circuitChip2", iron_nugget, "oc:circuitChip2"] - ["", "oc:materialCircuitBoardPrinted", ""]] -} -ram4 { - input: [["oc:circuitChip2", "oc:circuitChip3", "oc:circuitChip2"] - ["", "oc:materialCircuitBoardPrinted", ""]] -} -ram5 { - input: [["oc:circuitChip3", iron_nugget, "oc:circuitChip3"] - ["", "oc:materialCircuitBoardPrinted", ""]] -} -ram6 { - input: [["oc:circuitChip3", "oc:circuitChip3", "oc:circuitChip3"] - ["oc:circuitChip2", "oc:materialCircuitBoardPrinted", "oc:circuitChip2"]] -} - -eeprom { - input: [[nuggetGold, "oc:materialTransistor", nuggetGold] - [paper, "oc:circuitChip1", paper] - [nuggetGold, torchRedstoneActive, nuggetGold]] -} -floppy { - input: [[iron_nugget, lever, iron_nugget] - [paper, "oc:materialDisk", paper] - [iron_nugget, paper, iron_nugget]] -} -hdd1 { - input: [["oc:circuitChip1", "oc:materialDisk", ingotIron] - ["oc:materialCircuitBoardPrinted", "oc:materialDisk", craftingPiston] - ["oc:circuitChip1", "oc:materialDisk", ingotIron]] -} -hdd2 { - input: [["oc:circuitChip2", "oc:materialDisk", ingotGold] - ["oc:materialCircuitBoardPrinted", "oc:materialDisk", craftingPiston] - ["oc:circuitChip2", "oc:materialDisk", ingotGold]] -} -hdd3 { - input: [["oc:circuitChip3", "oc:materialDisk", gemDiamond] - ["oc:materialCircuitBoardPrinted", "oc:materialDisk", craftingPiston] - ["oc:circuitChip3", "oc:materialDisk", gemDiamond]] -} - -datacard1 { - input: [[iron_nugget, "oc:materialALU", "oc:circuitChip2"] - ["", "oc:materialCard", ""]] -} -datacard2 { - input: [[nuggetGold, "oc:cpu1", "oc:circuitChip3"] - ["", "oc:materialCard", ""]] -} -datacard3 { - input: [[chipDiamond, "oc:cpu2", "oc:ram5"] - ["", "oc:materialCard", ""]] -} -graphicscard1 { - input: [["oc:circuitChip1", "oc:materialALU", "oc:ram1"] - ["", "oc:materialCard", ""]] -} -graphicscard2 { - input: [["oc:circuitChip2", "oc:materialALU", "oc:ram3"] - ["", "oc:materialCard", ""]] -} -graphicscard3 { - input: [["oc:circuitChip3", "oc:materialALU", "oc:ram5"] - ["", "oc:materialCard", ""]] -} -internetcard { - input: [["oc:materialInterweb", "oc:circuitChip2", torchRedstoneActive] - ["", "oc:materialCard", obsidian]] -} -redstonecard1 { - input: [[torchRedstoneActive, "oc:circuitChip1", ""] - ["", "oc:materialCard", ""]] -} -redstonecard2 { - input: [[blockRedstone, "oc:circuitChip2", materialEnderPearl] - ["", "oc:materialCard", ""]] -} -lancard { - input: [["oc:cable", "oc:circuitChip1", ""] - ["", "oc:materialCard", ""]] -} -wlancard1 { - input: [[torchRedstoneActive, "oc:circuitChip1", torchRedstoneActive] - ["", "oc:materialCard", ""]] -} -wlancard2 { - input: [[materialEnderPearl, "oc:circuitChip2", ""] - ["", "oc:materialCard", ""]] -} -linkedcard { - input: [[eyeOfEnder, "", eyeOfEnder] - ["oc:lanCard", "oc:materialInterweb", "oc:lanCard"] - ["oc:circuitChip3", "", "oc:circuitChip3"]] - output: 2 # Note: all resulting cards are linked to each other. -} - -abstractbuscard { - input: [[{block="StargateTech2:block.busCable"}, {item="StargateTech2:naquadah", subID=3}, ""] - ["", "oc:materialCard", ""]] -} -worldsensorcard { - input: [[{item="galacticraftcore:sensor_lens"}, "oc:circuitChip2", ""] - ["", "oc:materialCard", ""]] -} - -angelupgrade { - input: [[ingotIron, materialEnderPearl, ingotIron] - ["oc:circuitChip1", pistonStickyBase, "oc:circuitChip1"] - [ingotIron, materialEnderPearl, ingotIron]] -} -batteryupgrade1 { - input: [[iron_nugget, nuggetGold, iron_nugget] - [fenceIron, "oc:capacitor", fenceIron] - [iron_nugget, nuggetGold, iron_nugget]] -} -batteryupgrade2 { - input: [[iron_nugget, "oc:capacitor", iron_nugget] - [fenceIron, nuggetGold, fenceIron] - [iron_nugget, "oc:capacitor", iron_nugget]] -} -batteryupgrade3 { - input: [[iron_nugget, "oc:capacitor", iron_nugget] - ["oc:capacitor", chipDiamond, "oc:capacitor"] - [iron_nugget, "oc:capacitor", iron_nugget]] -} -chunkloaderupgrade { - input: [[ingotGold, blockGlass, ingotGold] - ["oc:circuitChip3", eyeOfEnder, "oc:circuitChip3"] - [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] -} -craftingupgrade { - input: [[ingotIron, "", ingotIron] - ["oc:circuitChip1", workbench, "oc:circuitChip1"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -databaseupgrade1 { - input: [[ingotIron, "oc:analyzer", ingotIron] - ["oc:circuitChip1", "oc:hdd1", "oc:circuitChip1"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -databaseupgrade2 { - input: [[ingotIron, "oc:analyzer", ingotIron] - ["oc:circuitChip2", "oc:hdd2", "oc:circuitChip2"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -databaseupgrade3 { - input: [[ingotIron, "oc:analyzer", ingotIron] - ["oc:circuitChip3", "oc:hdd3", "oc:circuitChip3"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -experienceupgrade { - input: [[ingotGold, "", ingotGold] - ["oc:circuitChip2", emerald, "oc:circuitChip2"] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -generatorupgrade { - input: [[ingotIron, "", ingotIron] - ["oc:circuitChip1", craftingPiston, "oc:circuitChip1"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -hoverupgrade1 { - input: [[feather, "oc:circuitChip1", feather] - [iron_nugget, leather, iron_nugget] - [feather, "oc:materialCircuitBoardPrinted", feather]] -} -hoverupgrade2 { - input: [["oc:stoneEndstone", "oc:circuitChip2", "oc:stoneEndstone"] - [nuggetGold, ingotIron, nuggetGold] - ["oc:stoneEndstone", "oc:materialCircuitBoardPrinted", "oc:stoneEndstone"]] -} -inventoryupgrade { - input: [[plankWood, hopper, plankWood] - [dropper, chest, craftingPiston] - [plankWood, "oc:circuitChip1", plankWood]] -} -inventorycontrollerupgrade { - input: [[ingotGold, "oc:analyzer", ingotGold] - [dropper, "oc:circuitChip2", craftingPiston] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -mfu { - input: [["oc:chamelium", gemLapis, "oc:chamelium"] - ["oc:linkedCard", "oc:adapter", "oc:linkedCard"] - ["oc:chamelium", gemLapis, "oc:chamelium"]] -} -leashupgrade { - input: [[ingotIron, {item="minecraft:lead"}, ingotIron] - [{item="minecraft:lead"}, "oc:materialCU", {item="minecraft:lead"}] - [ingotIron, {item="minecraft:lead"}, ingotIron]] -} -navigationupgrade { - input: [[ingotGold, compass, ingotGold] - ["oc:circuitChip2", {item=filled_map, subID=any}, "oc:circuitChip2"] - [ingotGold, potion, ingotGold]] -} -pistonupgrade { - input: [[ingotIron, craftingPiston, ingotIron] - [stickWood, "oc:circuitChip1", stickWood] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -stickypistonupgrade { - type: shapeless - input: ["oc:pistonUpgrade", "minecraft:slime_ball"] - output: 1 -} -signupgrade { - input: [[ingotIron, dyeBlack, ingotIron] - ["oc:circuitChip1", stickWood, "oc:circuitChip1"] - [ingotIron, pistonStickyBase, ingotIron]] -} -solargeneratorupgrade { - input: [[blockGlass, blockGlass, blockGlass] - ["oc:circuitChip3", blockLapis, "oc:circuitChip3"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -tankupgrade { - input: [[plankWood, fenceIron, plankWood] - [dispenser, cauldron, craftingPiston] - [plankWood, "oc:circuitChip1", plankWood]] -} -tankcontrollerupgrade { - input: [[ingotGold, glassBottle, ingotGold] - [dispenser, "oc:circuitChip2", craftingPiston] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -tractorbeamupgrade { - input: [[ingotGold, craftingPiston, ingotGold] - [ingotIron, "oc:capacitor", ingotIron] - [ingotGold, "oc:circuitChip3", ingotGold]] -} -tradingupgrade { - input: [[ingotGold, chest, ingotGold] - [emerald, "oc:circuitChip2", emerald] - [dropper, "oc:materialCircuitBoardPrinted", craftingPiston]] -} - -cardcontainer1 { - input: [[ingotIron, "oc:circuitChip1", ingotIron] - [craftingPiston, chest, ""] - [ingotIron, "oc:materialCard", ingotIron]] -} -cardcontainer2 { - input: [[ingotIron, "oc:circuitChip2", ingotIron] - [craftingPiston, chest, ""] - [ingotIron, "oc:materialCard", ingotIron]] -} -cardcontainer3 { - input: [[ingotGold, "oc:circuitChip2", ingotGold] - [craftingPiston, chest, ""] - [ingotGold, "oc:materialCard", ingotGold]] -} -upgradecontainer1 { - input: [[ingotIron, "oc:circuitChip1", ingotIron] - [craftingPiston, chest, ""] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -upgradecontainer2 { - input: [[ingotIron, "oc:circuitChip2", ingotIron] - [craftingPiston, chest, ""] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -upgradecontainer3 { - input: [[ingotGold, "oc:circuitChip2", ingotGold] - [craftingPiston, chest, ""] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} - -ingotiron { - type: shapeless - input: [iron_nugget, iron_nugget, iron_nugget, - iron_nugget, iron_nugget, iron_nugget, - iron_nugget, iron_nugget, iron_nugget] -} -chipdiamond { - type: shapeless - input: ["oc:materialCuttingWire", gemDiamond] - output: 6 -} -gemDiamond = false - -cuttingwire { - input: [[stickWood, nuggetIron, stickWood]] -} -acid { - type: shapeless - input: [bucketWater, sugar, slimeball, fermentedSpiderEye, bone] -} -disk { - input: [["", iron_nugget, ""] - [iron_nugget, "", iron_nugget] - ["", iron_nugget, ""]] -} -chamelium { - input: [[gravel, redstone, gravel], - [redstone, {item=coal, subID=1}, redstone], - [gravel, {item="minecraft:water_bucket"}, gravel]] - output: 16 -} -chameliumblock { - input: [["oc:chamelium", "oc:chamelium", "oc:chamelium"], - ["oc:chamelium", "oc:chamelium", "oc:chamelium"], - ["oc:chamelium", "oc:chamelium", "oc:chamelium"]] -} -endstone { - input: [[materialEnderPearl, "oc:chameliumBlock", materialEnderPearl] - ["oc:chameliumBlock", materialEnderPearl, "oc:chameliumBlock"] - [materialEnderPearl, "oc:chameliumBlock", materialEnderPearl]] - output: 4 -} -inkcartridgeempty { - input: [[iron_nugget, dispenser, iron_nugget], - ["oc:materialTransistor", bucket, "oc:materialTransistor"], - [iron_nugget, "oc:materialCircuitBoardPrinted", iron_nugget]] -} -inkcartridge { - type: shapeless - input: [dyeCyan, dyeMagenta, dyeYellow, dyeBlack, "oc:inkCartridgeEmpty"] -} - -buttongroup { - input: [[button, button, button] - [button, button, button]] -} -arrowkeys { - input: [["", button, ""] - [button, button, button]] -} -numpad { - input: [[button, button, button] - [button, button, button] - [button, button, button]] -} - -transistor { - input: [[ingotIron, ingotIron, ingotIron] - [nuggetGold, paper, nuggetGold] - ["", redstone, ""]] - output: 8 -} -chip1 { - input: [[iron_nugget, iron_nugget, iron_nugget] - [redstone, "oc:materialTransistor", redstone] - [iron_nugget, iron_nugget, iron_nugget]] - output: 8 -} -chip2 { - input: [[nuggetGold, nuggetGold, nuggetGold] - [redstone, "oc:materialTransistor", redstone] - [nuggetGold, nuggetGold, nuggetGold]] - output: 4 -} -chip3 { - input: [[chipDiamond, chipDiamond, chipDiamond] - [redstone, "oc:materialTransistor", redstone] - [chipDiamond, chipDiamond, chipDiamond]] - output: 2 -} -alu { - input: [[iron_nugget, redstone, iron_nugget] - ["oc:materialTransistor", "oc:circuitChip1", "oc:materialTransistor"] - [iron_nugget, "oc:materialTransistor", iron_nugget]] -} -apu1 { - input: [[nuggetGold, "oc:circuitChip1", nuggetGold] - ["oc:cpu2", "oc:componentBus1", "oc:graphicsCard1"] - [nuggetGold, "oc:circuitChip1", nuggetGold]] -} -apu2 { - input: [[chipDiamond, "oc:circuitChip2", chipDiamond] - ["oc:cpu3", "oc:componentBus2", "oc:graphicsCard2"] - [chipDiamond, "oc:circuitChip2", chipDiamond]] -} -componentbus1 { - input: [[iron_nugget, redstone, iron_nugget] - ["oc:circuitChip1", "oc:materialCU", ""] - [iron_nugget, "oc:materialCircuitBoardPrinted", iron_nugget]] -} -componentbus2 { - input: [[nuggetGold, redstone, nuggetGold] - ["oc:circuitChip2", "oc:materialCU", ""] - [nuggetGold, "oc:materialCircuitBoardPrinted", nuggetGold]] -} -componentbus3 { - input: [[chipDiamond, redstone, chipDiamond] - ["oc:circuitChip3", "oc:materialCU", ""] - [chipDiamond, "oc:materialCircuitBoardPrinted", chipDiamond]] -} -cpu1 { - input: [[iron_nugget, redstone, iron_nugget] - ["oc:circuitChip1", "oc:materialCU", "oc:circuitChip1"] - [iron_nugget, "oc:materialALU", iron_nugget]] -} -cpu2 { - input: [[nuggetGold, redstone, nuggetGold] - ["oc:circuitChip2", "oc:materialCU", "oc:circuitChip2"] - [nuggetGold, "oc:materialALU", nuggetGold]] -} -cpu3 { - input: [[chipDiamond, redstone, chipDiamond] - ["oc:circuitChip3", "oc:materialCU", "oc:circuitChip3"] - [chipDiamond, "oc:materialALU", chipDiamond]] -} -cu { - input: [[nuggetGold, redstone, nuggetGold] - ["oc:materialTransistor", clock, "oc:materialTransistor"] - [nuggetGold, "oc:materialTransistor", nuggetGold]] -} - -rawcircuitboard { - type: shapeless - input: [ingotGold, clay, dyeGreen] - output: 8 -} -circuitboard = false -printedcircuitboard { - type: furnace - input: "oc:materialCircuitBoardRaw" -} -card { - input: [[iron_nugget, "", ""] - [iron_nugget, "oc:materialCircuitBoardPrinted", ""] - [iron_nugget, nuggetGold, ""]] -} - -interweb { - input: [[string, string, string] - [string, materialEnderPearl, string] - [string, string, string]] -} - -adapter { - input: [[ingotIron, "oc:cable", ingotIron] - ["oc:cable", "oc:circuitChip1", "oc:cable"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -assembler { - input: [[ingotIron, workbench, ingotIron] - [craftingPiston, "oc:circuitChip2", craftingPiston] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -cable { - input: [["", iron_nugget, ""] - [iron_nugget, redstone, iron_nugget] - ["", iron_nugget, ""]] - output: 4 -} -luaBios { - type: shapeless - input: ["oc:eeprom", "oc:manual"] -} -carpetedcapacitor { - type: shapeless - input: [carpet, "oc:capacitor"] -} -capacitor { - input: [[ingotIron, "oc:materialTransistor", ingotIron] - [nuggetGold, paper, nuggetGold] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -charger { - input: [[ingotIron, ingotGold, ingotIron] - ["oc:capacitor", "oc:circuitChip2", "oc:capacitor"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -case1 { - input: [[ingotIron, "oc:circuitChip1", ingotIron] - [fenceIron, chest, fenceIron] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -case2 { - input: [[ingotGold, "oc:circuitChip2", ingotGold] - [fenceIron, chest, fenceIron] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -case3 { - input: [[gemDiamond, "oc:circuitChip3", gemDiamond] - [fenceIron, chest, fenceIron] - [gemDiamond, "oc:materialCircuitBoardPrinted", gemDiamond]] -} -disassembler { - input: [["oc:materialCU", paneGlass, "oc:analyzer"] - [craftingPiston, "", obsidian] - [ingotIron, bucketLava, ingotIron]] -} -diskdrive { - input: [[ingotIron, "oc:circuitChip1", ingotIron] - [craftingPiston, stickWood, ""] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -geolyzer { - input: [[ingotGold, compass, ingotGold] - [eyeOfEnder, "oc:circuitChip2", eyeOfEnder] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -hologram1 { - input: [["oc:circuitChip2", paneGlass, "oc:circuitChip2"] - ["oc:materialCircuitBoardPrinted", chipDiamond, "oc:materialCircuitBoardPrinted"] - [obsidian, yellowDust, obsidian]] -} -hologram2 { - input: [["oc:circuitChip3", blockGlass, "oc:circuitChip3"] - ["oc:materialCircuitBoardPrinted", gemDiamond, "oc:materialCircuitBoardPrinted"] - [obsidian, blazePowder, obsidian]] -} -keyboard { - input: [["oc:materialButtonGroup", "oc:materialButtonGroup", "oc:materialButtonGroup"] - ["oc:materialButtonGroup", "oc:materialArrowKey", "oc:materialNumPad"]] -} -motionsensor { - input: [[ingotGold, daylightDetector, ingotGold] - [daylightDetector, "oc:cpu2", daylightDetector] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -netsplitter { - input: [[ingotIron, "oc:cable", ingotIron] - ["oc:cable", craftingPiston, "oc:cable"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -printer { - input: [[ingotIron, hopper, ingotIron] - [craftingPiston, "oc:circuitChip3", craftingPiston] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -powerconverter { - input: [[ingotIron, "oc:cable", ingotIron] - [ingotGold, "oc:circuitChip1", ingotGold] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -powerdistributor { - input: [[ingotIron, ingotGold, ingotIron] - ["oc:cable", "oc:circuitChip1", "oc:cable"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -rack { - input: [[gemDiamond, "oc:wlanCard2", gemDiamond] - [fenceIron, chest, fenceIron] - ["oc:relay", "oc:materialCircuitBoardPrinted", "oc:powerDistributor"]] -} -raid { - input: [[iron_nugget, "oc:cpu3", iron_nugget] - ["oc:ram1", "oc:diskDrive", "oc:ram1"] - [iron_nugget, "oc:circuitChip2", iron_nugget]] -} -redstone { - input: [[ingotIron, "oc:circuitChip3", ingotIron] - [blockRedstone, "oc:redstoneCard1", blockRedstone] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -relay { - input: [[ingotIron, "oc:cable", ingotIron] - ["oc:cable", "oc:lanCard", "oc:cable"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -screen1 { - input: [[ingotIron, redstone, ingotIron] - [redstone, "oc:circuitChip1", blockGlass] - [ingotIron, redstone, ingotIron]] -} -screen2 { - input: [[ingotGold, dyeRed, ingotGold] - [dyeGreen, "oc:circuitChip2", blockGlass] - [ingotGold, dyeBlue, ingotGold]] -} -screen3 { - input: [[obsidian, yellowDust, obsidian] - [yellowDust, "oc:circuitChip3", blockGlass] - [obsidian, yellowDust, obsidian]] -} -transposer { - input: [[ingotIron, "oc:inventoryControllerUpgrade", ingotIron] - [hopper, bucket, hopper] - [ingotIron, "oc:tankControllerUpgrade", ingotIron]] - output: 4 -} -waypoint { - input: [[ingotIron, "oc:circuitChip1", ingotIron] - ["oc:materialTransistor", "oc:materialInterweb", "oc:materialTransistor"], - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} diff --git a/src/main/resources/assets/opencomputers/recipes/gregtech.recipes b/src/main/resources/assets/opencomputers/recipes/gregtech.recipes deleted file mode 100644 index 1c3a45134d..0000000000 --- a/src/main/resources/assets/opencomputers/recipes/gregtech.recipes +++ /dev/null @@ -1,353 +0,0 @@ -# Do not change this file, it is rewritten each time you start the game. -# Instead, use the user.recipes file to edit recipes by redefining them there. - -# Note that there is support for a number of GregTech machines, by using the -# appropriate `type` specifier. Available types are: -# - gt_alloySmelter : Alloy Smelter Recipe -# - gt_assembler : Circuit Assembler Machine -# - gt_bender : Plate Bending Machine Recipe -# - gt_canner : Canning Machine Recipe -# - gt_chemical : Chemical Recipe -# - gt_cnc : CNC-Machine Recipe -# - gt_cutter : Cutter Recipe -# - gt_fluidCanner : Fluid Canner Recipe -# - gt_formingPress : Forming Press Recipe -# - gt_lathe : Lathe Machine Recipe -# - gt_laserEngraver: Laser Engraver Recipe -# - gt_wiremill : Wiremill Recipe -# -# For these types, there a few more options for inputs and outputs. A full -# recipe using all these options would look like this: -# name { -# type: gt_??? -# input: ["primaryInput", "possiblyOptionalSecondaryInput"] -# count: [1, 2] # would mean 1 of primary, 2 of secondary -# output: 2 # size of primary output stack -# eu: EU consumed for the operation -# time: time it takes to complete the operation, in ticks. -# # The following are usually optional. -# secondaryOutput: ["secondaryOutput1", "secondaryOutput2"] # Max number depends on machine. -# secondaryOutputCount: [2, 2] # Like `count` to `input`. -# inputFluid: {name="water", amount="500"} -# outputFluid: {name="lava"} # defaults to amount = 1000 -# } - -include file("hardmode.recipes") - -analyzer { - # 32762 = Portable Scanner - input: [["oc:materialTransistor", torchRedstoneActive, "oc:materialTransistor"] - ["oc:circuitChip2", {item="gt.metaitem.01", subID=32762}, "oc:circuitChip2"] - [screwAluminium, craftingToolScrewdriver, screwAluminium]] -} - -server1 { - input: [["oc:circuitChip1", "oc:ram4", "oc:circuitChip1"] - ["oc:circuitChip2", "oc:case1", "oc:circuitChip2"] - [craftingToolScrewdriver, "oc:materialCircuitBoardPrinted", craftingToolWrench]] -} -server2 { - input: [["oc:circuitChip2", "oc:ram5", "oc:circuitChip2"] - ["oc:circuitChip3", "oc:case2", "oc:circuitChip3"] - [craftingToolScrewdriver, "oc:materialCircuitBoardPrinted", craftingToolWrench]] -} -server3 { - input: [["oc:circuitChip3", "oc:ram6", "oc:circuitChip3"] - ["oc:circuitChip3", "oc:case3", "oc:circuitChip3"] - [craftingToolScrewdriver, "oc:materialCircuitBoardPrinted", craftingToolWrench]] -} - -ram1 { - type: gt_assembler - input: ["oc:circuitChip1", "oc:materialCircuitBoardPrinted"] - count: [3, 3] - eu: 32 - time: 250 -} -ram2 { - input: [["oc:circuitChip1", "oc:circuitChip1", "oc:circuitChip1"] - ["oc:ram1", "oc:materialCircuitBoardPrinted", "oc:ram1"] - ["", craftingToolWrench, ""]] -} -ram3 { - input: [["oc:circuitChip2", "oc:circuitChip2", "oc:circuitChip2"] - ["oc:ram2", "oc:materialCircuitBoardPrinted", "oc:ram2"] - [circuitElite, craftingToolWrench, circuitElite]] -} -ram4 { - input: [["oc:circuitChip2", "oc:circuitChip2", "oc:circuitChip2"] - ["oc:ram3", "oc:materialCircuitBoardPrinted", "oc:ram3"] - [circuitElite, craftingToolWrench, circuitElite]] -} -ram5 { - input: [["oc:circuitChip3", "oc:circuitChip3", "oc:circuitChip3"] - ["oc:ram4", "oc:materialCircuitBoardPrinted", "oc:ram4"] - [circuitUltimate, craftingToolWrench, circuitUltimate]] -} -ram6 { - input: [["oc:circuitChip3", "oc:circuitChip3", "oc:circuitChip3"] - ["oc:ram5", "oc:materialCircuitBoardPrinted", "oc:ram5"] - [circuitUltimate, craftingToolWrench, circuitUltimate]] -} - -floppy { - input: [[screwAluminium, lever, screwAluminium] - [plateAluminium, "oc:materialDisk", plateAluminium] - [screwAluminium, craftingToolScrewdriver, screwAluminium]] -} -hdd1 { - input: [["oc:ram1", "oc:materialDisk", "oc:ram1"] - ["oc:ram1", "oc:materialDisk", "oc:ram1"] - [screwAluminium, craftingToolScrewdriver, "oc:circuitChip2"]] -} -hdd2 { - input: [["oc:hdd1", "oc:materialCircuitBoardPrinted" , "oc:hdd1"] - ["oc:circuitChip2", screwTitanium, "oc:circuitChip2"] - [screwTitanium, craftingToolScrewdriver, screwTitanium]] -} -hdd3 { - input: [["oc:hdd2", "oc:materialCircuitBoardPrinted", "oc:hdd2"] - ["oc:circuitChip3", screwTungstenSteel, "oc:circuitChip3"] - [screwTungstenSteel , craftingToolScrewdriver, screwTungstenSteel]] -} - -# graphicsCard1 { fallback to default } -# graphicsCard2 { fallback to default } -# graphicsCard3 { fallback to default } -redstonecard { - input: [[screwStainlessSteel , "oc:circuitChip2" , screwStainlessSteel] - ["comparator", "oc:materialCard", diode] - [screwStainlessSteel , craftingToolScrewdriver, screwStainlessSteel]] -} -lancard { - input: [[screwStainlessSteel , "oc:circuitChip2" , screwStainlessSteel] - ["oc:cable", "oc:materialCard", "oc:cable"] - [screwStainlessSteel , craftingToolScrewdriver, screwStainlessSteel]] -} -wlancard1 { - input: [[screwAluminium , "oc:circuitChip2" , screwAluminium] - [torchRedstoneActive, "oc:lanCard", torchRedstoneActive] - [screwAluminium , craftingToolScrewdriver, screwAluminium]] -} -wlancard2 { - input: [[screwTitanium , "oc:circuitChip3" , screwTitanium] - [materialEnderPearl, "oc:lanCard", materialEnderPearl] - [screwTitanium , craftingToolScrewdriver, screwTitanium]] -} - -craftingupgrade { - # 1 = LV Casing - input: [[screwStainlessSteel, "oc:materialCircuitBoardPrinted" , screwStainlessSteel] - ["oc:circuitChip2", {block="gt.blockcasings", subID=1}, "oc:circuitChip2"] - [screwStainlessSteel, craftingToolScrewdriver, screwStainlessSteel]] -} -generatorupgrade { - input: [[screwStainlessSteel, "oc:materialCircuitBoardPrinted" , screwStainlessSteel] - ["oc:circuitChip2", craftingGenerator, "oc:circuitChip2"] - [screwStainlessSteel, craftingToolScrewdriver, screwStainlessSteel]] -} -navigationupgrade { - # 2 = MV Casing - input: [[{block="gt.blockcasings", subID=2}, compass, screwStainlessSteel] - ["oc:circuitChip3", {item=filled_map, subID=any}, "oc:circuitChip3"] - [screwStainlessSteel, potion, craftingToolScrewdriver]] -} -signupgrade { - input: [[screwAluminium, dyeBlack, screwAluminium] - ["oc:circuitChip1", stickWood, "oc:circuitChip1"] - [screwAluminium, craftingToolScrewdriver, screwAluminium]] -} -solargeneratorupgrade { - # 32750 = Solar Panel - input: [[screwTitanium, "", screwTitanium] - ["oc:circuitChip3", {item="gt.metaitem.01", subID=32750} , "oc:circuitChip3"] - [screwTitanium, craftingToolScrewdriver, screwTitanium]] -} - -cuttingwire { - input: [[stickWood, ingotTin, stickWood] - ["", craftingToolWireCutter, ""]] -} -disk { - input: [["", plateAluminium, ""] - [plateAluminium, "", plateAluminium] - ["", plateAluminium, ""]] -} - -# buttonGroup { fallback to default } -# arrowKeys { fallback to default } -# numPad { fallback to default } - -transistor { - type: gt_assembler - input: [redstone, stickIron] - count: [1, 3] - eu: 16 - time: 500 - output: 6 -} -chip1 { - type: gt_assembler - input: ["ic2.itemPartCircuit", "oc:materialTransistor"] - count: [1, 4] - eu: 25 - time: 480 - output: 4 -} -chip2 { - type: gt_assembler - input: ["ic2.itemPartCircuitAdv", "oc:materialTransistor"] - count: [1, 8] - eu: 25 - time: 640 - output: 4 -} -chip3 { - type: gt_assembler - input: [circuitData, "oc:materialTransistor"] - count: [1, 16] - eu: 25 - time: 800 - output: 4 -} -alu { - type: gt_assembler - input: [comparator, "oc:circuitChip1"] - count: [3, 1] - eu: 24 - time: 500 - output: 1 -} -cpu1 { - input: [["oc:circuitChip2", "oc:materialALU", "oc:circuitChip2"] - [plateAluminium, "oc:materialCU", plateAluminium] - [screwAluminium, craftingToolScrewdriver, screwAluminium]] -} -cpu2 { - input: [["oc:circuitChip2", plateStainlessSteel, "oc:circuitChip2"] - ["oc:ram3", "oc:cpu1", "oc:ram3"] - ["oc:circuitChip2", craftingToolScrewdriver, "oc:circuitChip2"]] -} -cpu3 { - input: [["oc:circuitChip3", plateTitanium, "oc:circuitChip3"] - ["oc:ram5", "oc:cpu2", "oc:ram5"] - ["oc:circuitChip3", craftingToolScrewdriver, "oc:circuitChip3"]] -} -cu { - type: gt_assembler - input: [circuitElite, "oc:materialTransistor"] - count: [1, 6] - eu: 32 - time: 750 - output: 3 -} - -# rawCircuitBoard { fallback to default } -circuitboard { - type: furnace - input: "oc:materialCircuitBoardRaw" -} -printedcircuitboard { - type:shaped - input: [[dustTinyGold, cellSulfuricAcid] - ["oc:materialCircuitBoard", dustTinyGold]] -} -card { - input: [[stickIron, "oc:circuitChip2", "oc:materialTransistor"] - [stickIron, "oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted"] - [craftingToolScrewdriver, nuggetGold, nuggetGold]] -} - -adapter { - input: [["oc:cable", "oc:circuitChip1", "oc:cable"] - ["", {block="gt.blockcasings", subID=1}, ""] - ["oc:materialCircuitBoardPrinted", "oc:cable", craftingToolWrench]] -} -cable { - type: gt_assembler - input: [craftingWireCopper, dustEmerald] - count: [8, 1] - eu: 32 - time: 64 - output: 8 -} -carpetedcapacitor { - type: shapeless - input: [carpet, "oc:capacitor"] -} -capacitor { - # 7 = CESU - input: [["", {item="ic2.blockElectric", subID=7}, ""] - [{block="gt.blockcasings", subID=1}, "oc:materialTransistor", {block="gt.blockcasings", subID=1}] - ["oc:materialCircuitBoardPrinted", craftingToolWrench, "oc:materialCircuitBoardPrinted"]] -} -charger { - # 2 = Chargepad (MFE) - input: [["", plateStainlessSteel, ""] - [{item="ic2.blockChargepad", subID=2}, {block="gt.blockcasings", subID=3}, {item="ic2.blockChargepad", subID=2}] - ["oc:circuitChip3", craftingToolWrench, "oc:materialCircuitBoardPrinted"]] -} -case1 { - input: [[screwAluminium, "oc:materialCircuitBoardPrinted", craftingToolWrench] - ["ic2.reactorVentSpread", {block="gt.blockcasings", subID=1}, "ic2.reactorVentSpread"] - [screwAluminium, "oc:circuitChip1", craftingToolScrewdriver]] -} -case2 { - input: [[screwStainlessSteel , "oc:materialCircuitBoardPrinted", craftingToolWrench] - [{item="ic2.reactorVentGold", subID=1}, "oc:case1", {item="ic2.reactorVentGold", subID=1}] - [screwStainlessSteel, "oc:circuitChip2", craftingToolScrewdriver]] -} -case3 { - input: [[screwTitanium , "oc:materialCircuitBoardPrinted", craftingToolWrench] - [{item="ic2.reactorVentDiamond", subID=1}, "oc:case2", {item="ic2.reactorVentDiamond", subID=1}] - [screwTitanium, "oc:circuitChip3", craftingToolScrewdriver]] -} -diskdrive { - input: [["", "oc:circuitChip2", ""] - [craftingPiston, {block="gt.blockcasings", subID=1}, craftingLensWhite] - ["oc:circuitChip2", craftingToolWrench, "oc:circuitChip2"]] -} -# keyboard { fallback to default } -powerconverter { - # 4 = MV Transformer - input: [["", "oc:circuitChip2", ""] - [plateAluminium, {item="ic2.blockElectric", subID=4}, plateAluminium] - ["oc:materialCircuitBoardPrinted", craftingToolWrench, "oc:materialCircuitBoardPrinted"]] -} -powerdistributor { - # 7 = CESU - input: [["", plateAluminium, ""] - [{item="ic2.blockElectric", subID=7}, {block="gt.blockcasings", subID=2}, circuitMaster] - ["oc:materialCircuitBoardPrinted", plateAluminium, craftingToolWrench]] -} -rack { - input: [[craftingToolScrewdriver, "oc:wlanCard2", craftingToolWrench] - [{item="ic2.reactorVentDiamond", subID=1}, chest, {item="ic2.reactorVentDiamond", subID=1}] - ["oc:relay", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]] -} -redstone { - # 32731 = Activity Detector - input: [[plateRedstone, "oc:materialCircuitBoardPrinted", plateRedstone] - [{item="gt.metaitem.01", subID=32731}, {block="gt.blockcasings", subID=2}, "oc:redstoneCard1"] - ["oc:circuitChip2", "oc:materialCircuitBoardPrinted", "oc:circuitChip2"]] -} -relay { - input: [["", "oc:lanCard", ""] - ["oc:cable", {block="gt.blockcasings", subID=2}, "oc:cable"] - ["oc:materialCircuitBoardPrinted", craftingToolWrench, "oc:materialCircuitBoardPrinted"]] -} -screen1 { - input: [[plateAluminium, plateAluminium, craftingToolWrench] - [redstone, "oc:materialTransistor", paneGlass] - [plateAluminium, plateAluminium, craftingToolScrewdriver]] -} -screen2 { - input: [[plateStainlessSteel, screwStainlessSteel, craftingToolWrench] - ["oc:circuitChip2", "oc:screen1", {item="gt.metaitem.01", subID=32740}] - [plateStainlessSteel, screwStainlessSteel, craftingToolScrewdriver]] -} -screen3 { - input: [[plateTitanium, "oc:materialCircuitBoardPrinted", craftingToolWrench] - ["oc:circuitChip3", "oc:screen2", "oc:circuitChip3"] - [plateTitanium, "oc:materialCircuitBoardPrinted", craftingToolScrewdriver]] -} diff --git a/src/main/resources/assets/opencomputers/recipes/hardmode.recipes b/src/main/resources/assets/opencomputers/recipes/hardmode.recipes deleted file mode 100644 index 14cc0646af..0000000000 --- a/src/main/resources/assets/opencomputers/recipes/hardmode.recipes +++ /dev/null @@ -1,411 +0,0 @@ -# Do not change this file, it is rewritten each time you start the game. -# Instead, use the user.recipes file to edit recipes by redefining them there. - -include file("default.recipes") - -analyzer { - input: [["", torchRedstoneActive, ""] - ["oc:materialTransistor", "oc:circuitChip1", nuggetGold] - ["oc:materialTransistor", "oc:materialCircuitBoardPrinted", nuggetGold]] -} -terminal { - input: [[iron_nugget, "oc:solarGeneratorUpgrade", iron_nugget] - ["oc:circuitChip3", "oc:screen2", "oc:wlanCard2"] - [iron_nugget, "oc:keyboard", iron_nugget]] -} - -server1 { - input: [["oc:circuitChip1", "oc:ram4", "oc:circuitChip1"] - ["oc:circuitChip2", "oc:case1", "oc:circuitChip2"] - ["oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted"]] -} -server2 { - input: [["oc:circuitChip2", "oc:ram5", "oc:circuitChip2"] - ["oc:circuitChip3", "oc:case2", "oc:circuitChip3"] - ["oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted"]] -} -server3 { - input: [["oc:circuitChip3", "oc:ram6", "oc:circuitChip3"] - ["oc:circuitChip3", "oc:case3", "oc:circuitChip3"] - ["oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted"]] -} - -ram1 { - input: [["oc:circuitChip1", "oc:circuitChip1", "oc:circuitChip1"] - ["oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted"]] -} -ram2 { - input: [["oc:circuitChip1", "oc:circuitChip1", "oc:circuitChip1"] - ["oc:ram1", "oc:materialCircuitBoardPrinted", "oc:ram1"]] -} -ram3 { - input: [["oc:circuitChip2", "oc:circuitChip2", "oc:circuitChip2"] - ["oc:ram2", "oc:materialCircuitBoardPrinted", "oc:ram2"]] -} -ram4 { - input: [["oc:circuitChip2", "oc:circuitChip2", "oc:circuitChip2"] - ["oc:ram3", "oc:materialCircuitBoardPrinted", "oc:ram3"]] -} -ram5 { - input: [["oc:circuitChip3", "oc:circuitChip3", "oc:circuitChip3"] - ["oc:ram4", "oc:materialCircuitBoardPrinted", "oc:ram4"]] -} -ram6 { - input: [["oc:circuitChip3", "oc:circuitChip3", "oc:circuitChip3"] - ["oc:ram5", "oc:materialCircuitBoardPrinted", "oc:ram5"]] -} - -floppy { - input: [[iron_nugget, lever, iron_nugget] - ["oc:materialCircuitBoard", "oc:materialDisk", "oc:materialCircuitBoard"] - [iron_nugget, paper, iron_nugget]] -} -hdd1 { - input: [["oc:circuitChip1", "oc:materialDisk", ingotIron] - ["oc:materialCircuitBoardPrinted", "oc:materialDisk", craftingPiston] - ["oc:circuitChip1", "oc:materialDisk", ingotIron]] -} -hdd2 { - input: [[ingotGold, "oc:hdd1", ingotGold] - ["oc:circuitChip2", "oc:materialCircuitBoardPrinted", "oc:circuitChip2"] - [ingotGold, "oc:hdd1", ingotGold]] -} -hdd3 { - input: [["oc:circuitChip3", "oc:hdd2", "oc:circuitChip3"] - ["oc:ram1", "oc:materialCircuitBoardPrinted", "oc:ram1"] - ["oc:circuitChip3", "oc:hdd2", "oc:circuitChip3"]] -} - -abstractbuscard { - input: [[{block="StargateTech2:block.busCable"}, {item="StargateTech2:naquadah", subID=3}, ""] - ["", "oc:materialCard", ""]] -} -datacard2 { - input: [[nuggetGold, "oc:cpu1", "oc:circuitChip3"] - ["", "oc:dataCard1", ""]] -} -datacard3 { - input: [[gemDiamond, "oc:cpu2", "oc:ram5"] - ["", "oc:dataCard2", ""]] -} -graphicscard1 { - input: [["oc:circuitChip1", "oc:materialALU", "oc:ram1"] - ["", "oc:materialCard", ""]] -} -graphicscard2 { - input: [["oc:circuitChip2", "oc:circuitChip2", "oc:ram3"] - ["", "oc:graphicsCard1", ""]] -} -graphicscard3 { - input: [["oc:circuitChip3", "oc:circuitChip3", "oc:ram5"] - ["", "oc:graphicsCard2", ""]] -} -internetcard { - input: [["oc:materialInterweb", "oc:circuitChip3", torchRedstoneActive] - ["", "oc:wlanCard2", obsidian]] -} -redstonecard1 { - input: [[torchRedstoneActive, "oc:circuitChip1", ""] - ["", "oc:materialCard", ""]] -} -redstonecard2 { - input: [[blockRedstone, "oc:circuitChip2", materialEnderPearl] - ["", "oc:redstoneCard1", ""]] -} -lancard { - input: [["oc:cable", "oc:circuitChip1", ""] - ["", "oc:materialCard", ""]] -} -wlancard1 { - input: [[torchRedstoneActive, "oc:circuitChip1", torchRedstoneActive] - ["", "oc:lanCard", ""]] -} -wlancard2 { - input: [[materialEnderPearl, "oc:circuitChip2", ""] - ["", "oc:lanCard", ""]] -} -linkedcard { - input: [[eyeOfEnder, "", eyeOfEnder] - ["oc:wlanCard2", "oc:materialInterweb", "oc:wlanCard2"] - ["oc:circuitChip3", "", "oc:circuitChip3"]] - output: 2 # Note: all resulting cards are linked to each other. -} - -batteryupgrade1 { - input: [[ingotIron, nuggetGold, ingotIron] - ["oc:materialTransistor", "oc:capacitor", "oc:materialTransistor"] - [ingotIron, nuggetGold, ingotIron]] -} -batteryupgrade2 { - input: [[ingotGold, "oc:capacitor", ingotGold] - ["oc:materialTransistor", nuggetGold, "oc:materialTransistor"] - [ingotGold, "oc:capacitor", ingotGold]] -} -batteryupgrade3 { - input: [[gemDiamond, "oc:capacitor", gemDiamond] - ["oc:materialTransistor", "oc:capacitor", "oc:materialTransistor"] - [gemDiamond, "oc:capacitor", gemDiamond]] -} -craftingupgrade { - input: [[ingotIron, craftingPiston, ingotIron] - ["oc:circuitChip1", workbench, "oc:circuitChip1"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -experienceupgrade { - input: [[ingotGold, "oc:analyzer", ingotGold] - ["oc:circuitChip3", emerald, "oc:circuitChip3"] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -generatorupgrade { - input: [[ingotIron, "", ingotIron] - ["oc:circuitChip1", craftingPiston, "oc:circuitChip1"] - ["oc:materialCircuitBoardPrinted", ingotIron, "oc:materialCircuitBoardPrinted"]] -} -inventoryupgrade { - input: [[ingotIron, hopper, ingotIron] - [dispenser, chest, craftingPiston] - [ingotIron, "oc:circuitChip1", ingotIron]] -} -inventorycontrollerupgrade { - input: [[ingotGold, "oc:circuitChip2", ingotGold] - [dispenser, "oc:inventoryUpgrade", craftingPiston] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -navigationupgrade { - input: [[ingotGold, compass, ingotGold] - ["oc:circuitChip3", {item=filled_map, subID=any}, "oc:circuitChip3"] - [ingotGold, potion, ingotGold]] -} -signupgrade { - input: [[ingotIron, dyeBlack, ingotIron] - ["oc:circuitChip1", stickWood, "oc:circuitChip1"] - [ingotIron, pistonStickyBase, ingotIron]] -} -solargeneratorupgrade { - input: [[blockGlass, blockGlass, blockGlass] - ["oc:circuitChip3", "oc:generatorUpgrade", "oc:circuitChip3"]] -} -tradingupgrade { - input: [["oc:circuitChip2", chest, "oc:circuitChip2"] - [emerald, "oc:circuitChip2", emerald] - [dropper, "oc:materialCircuitBoardPrinted", craftingPiston]] -} - -cuttingwire { - input: [[stickWood, iron_nugget, stickWood]] -} -disk { - input: [["", iron_nugget, ""] - [iron_nugget, "", iron_nugget] - ["", iron_nugget, ""]] -} - -buttongroup { - input: [[button, button, button] - [button, button, button]] -} -arrowkeys { - input: [["", button, ""] - [button, button, button]] -} -numpad { - input: [[button, button, button] - [button, button, button] - [button, button, button]] -} - -transistor { - input: [[iron_nugget, iron_nugget, iron_nugget] - [nuggetGold, paper, nuggetGold] - ["", redstone, ""]] -} -chip1 { - input: [[iron_nugget, "", iron_nugget] - ["oc:materialTransistor", nuggetGold, "oc:materialTransistor"] - [iron_nugget, "", iron_nugget]] -} -chip2 { - input: [[nuggetGold, {item=dyePowder, subID=4} , nuggetGold] - ["oc:circuitChip1", netherquartz, "oc:circuitChip1"] - [nuggetGold, {item=dyePowder, subID=4}, nuggetGold]] -} -chip3 { - input: [[yellowDust, comparator, yellowDust] - ["oc:circuitChip2", gemDiamond, "oc:circuitChip2"] - [yellowDust, comparator, yellowDust]] -} -alu { - input: [[diode, torchRedstoneActive, diode] - ["oc:materialTransistor", "oc:materialTransistor", "oc:materialTransistor"] - [iron_nugget, redstone, iron_nugget]] -} -apu2 { - input: [[gemDiamond, "oc:circuitChip2", gemDiamond] - ["oc:cpu3", "oc:componentBus2", "oc:graphicsCard2"] - [gemDiamond, "oc:circuitChip2", gemDiamond]] -} -componentbus1 { - input: [[iron_nugget, redstone, iron_nugget] - ["oc:circuitChip1", "oc:materialCU", ""] - [iron_nugget, "oc:materialCircuitBoardPrinted", iron_nugget]] -} -componentbus2 { - input: [[nuggetGold, "oc:ram3", nuggetGold] - ["oc:circuitChip2", "oc:componentBus1", ""] - [nuggetGold, "oc:materialCircuitBoardPrinted", nuggetGold]] -} -componentbus3 { - input: [[gemDiamond, "oc:ram5", gemDiamond] - ["oc:circuitChip3", "oc:componentBus2", ""] - [gemDiamond, "oc:materialCircuitBoardPrinted", gemDiamond]] -} -cpu1 { - input: [[iron_nugget, redstone, iron_nugget] - ["oc:circuitChip1", "oc:materialCU", "oc:circuitChip1"] - [iron_nugget, "oc:materialALU", iron_nugget]] -} -cpu2 { - input: [[nuggetGold, "oc:ram3", nuggetGold] - ["oc:circuitChip2", "oc:cpu1", "oc:circuitChip2"] - [nuggetGold, "oc:ram3", nuggetGold]] -} -cpu3 { - input: [[gemDiamond, "oc:ram5", gemDiamond] - ["oc:circuitChip3", "oc:cpu2", "oc:circuitChip3"] - [gemDiamond, "oc:ram5", gemDiamond]] -} -cu { - input: [[nuggetGold, torchRedstoneActive, nuggetGold] - ["oc:materialTransistor", clock, "oc:materialTransistor"] - [nuggetGold, redstone, nuggetGold]] -} - -rawcircuitboard { - type: shapeless - input: ["oc:materialCuttingWire", clay, dyeGreen] -} -circuitboard { - type: furnace - input: "oc:materialCircuitBoardRaw" -} -printedcircuitboard { - type: shapeless - input: ["oc:materialCircuitBoard", nuggetGold, "oc:materialAcid"] - output: 1 -} -card { - input: [[iron_nugget, "oc:circuitChip1", "oc:materialTransistor"] - [iron_nugget, "oc:materialCircuitBoardPrinted", "oc:materialCircuitBoardPrinted"] - [iron_nugget, nuggetGold, nuggetGold]] -} - -interweb { - input: [[string, materialEnderPearl, string] - [materialEnderPearl, string, materialEnderPearl] - [string, materialEnderPearl, string]] -} - -adapter { - input: [[ingotIron, "oc:cable", ingotIron] - ["oc:cable", "oc:circuitChip1", "oc:cable"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -cable { - input: [["", iron_nugget, ""] - [iron_nugget, redstone, iron_nugget] - ["", iron_nugget, ""]] - output: 4 -} -carpetedcapacitor { - type: shapeless - input: [carpet, "oc:capacitor"] -} -capacitor { - input: [[ingotIron, "oc:materialTransistor", ingotIron] - [nuggetGold, paper, nuggetGold] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -charger { - input: [[ingotIron, ingotGold, ingotIron] - ["oc:capacitor", "oc:circuitChip2", "oc:capacitor"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -case1 { - input: [[ingotIron, "oc:circuitChip1", ingotIron] - [fenceIron, chest, fenceIron] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -case2 { - input: [[ingotGold, "oc:circuitChip2", ingotGold] - ["oc:circuitChip2", "oc:case1", "oc:circuitChip2"] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -case3 { - input: [[gemDiamond, "oc:circuitChip3", gemDiamond] - ["oc:circuitChip3", "oc:case2", "oc:circuitChip3"] - [gemDiamond, "oc:materialCircuitBoardPrinted", gemDiamond]] -} -diskdrive { - input: [[ingotIron, "oc:circuitChip1", ingotIron] - [craftingPiston, stickWood, ""] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -geolyzer { - input: [[ingotGold, "oc:analyzer", ingotGold] - [eyeOfEnder, "oc:circuitChip2", eyeOfEnder] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -hologram1 { - input: [["oc:circuitChip2", paneGlass, "oc:circuitChip2"] - ["oc:materialCircuitBoardPrinted", gemDiamond, "oc:materialCircuitBoardPrinted"] - [obsidian, yellowDust, obsidian]] -} -hologram2 { - input: [["oc:circuitChip3", blockGlass, "oc:circuitChip3"] - ["oc:materialCircuitBoardPrinted", blockDiamond, "oc:materialCircuitBoardPrinted"] - [obsidian, blazePowder, obsidian]] -} -keyboard { - input: [["oc:materialButtonGroup", "oc:materialButtonGroup", "oc:materialButtonGroup"] - ["oc:materialButtonGroup", "oc:materialArrowKey", "oc:materialNumPad"]] -} -powerconverter { - input: [[ingotIron, "oc:cable", ingotIron] - [ingotGold, "oc:circuitChip1", ingotGold] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -powerdistributor { - input: [[ingotIron, ingotGold, ingotIron] - ["oc:cable", "oc:circuitChip1", "oc:cable"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -rack { - input: [["oc:circuitChip3", "oc:wlanCard2", "oc:circuitChip3"] - [fenceIron, chest, fenceIron] - ["oc:relay", "oc:materialCircuitBoardPrinted","oc:powerDistributor"]] -} -redstone { - input: [[ingotIron, "oc:circuitChip3", ingotIron] - [blockRedstone, "oc:redstoneCard1", blockRedstone] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -relay { - input: [[ingotIron, "oc:cable", ingotIron] - ["oc:cable", "oc:lanCard", "oc:cable"] - [ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]] -} -screen1 { - input: [[ingotIron, ingotIron, blockGlass] - [redstone, "oc:materialTransistor", blockGlass] - [ingotIron, ingotIron, blockGlass]] -} -screen2 { - input: [[ingotGold, dyeRed, ingotGold] - ["oc:circuitChip2", dyeGreen, "oc:screen1"] - [ingotGold, dyeBlue, ingotGold]] -} -screen3 { - input: [[obsidian, "oc:materialCircuitBoardPrinted", "oc:circuitChip3"] - [blazeRod, netherquartz, "oc:screen2"] - [obsidian, "oc:materialCircuitBoardPrinted", "oc:circuitChip3"]] -} diff --git a/src/main/resources/assets/opencomputers/recipes/peaceful.recipes b/src/main/resources/assets/opencomputers/recipes/peaceful.recipes deleted file mode 100644 index 83b57cd219..0000000000 --- a/src/main/resources/assets/opencomputers/recipes/peaceful.recipes +++ /dev/null @@ -1,79 +0,0 @@ -include file("default.recipes") - -redstonecard2 { - input: [[blockRedstone, "oc:circuitChip2", gemDiamond] - ["", "oc:materialCard", ""]] -} -wlancard1 { - input: [[torchRedstoneActive, "oc:circuitChip1", torchRedstoneActive] - ["", "oc:materialCard", ""]] -} -wlancard2 { - input: [[gemDiamond, "oc:circuitChip2", ""] - ["", "oc:materialCard", ""]] -} -linkedcard { - input: [[gemDiamond, "", gemDiamond] - ["oc:lanCard", "oc:materialInterweb", "oc:lanCard"] - ["oc:circuitChip3", "", "oc:circuitChip3"]] - output: 2 # Note: all resulting cards are linked to each other. -} - -angelupgrade { - input: [[ingotIron, gemDiamond, ingotIron] - ["oc:circuitChip1", pistonStickyBase, "oc:circuitChip1"] - [ingotIron, gemDiamond, ingotIron]] -} -chunkloaderupgrade { - input: [[ingotGold, blockGlass, ingotGold] - ["oc:circuitChip3", gemDiamond, "oc:circuitChip3"] - [obsidian, "oc:materialCircuitBoardPrinted", obsidian]] -} -inventoryupgrade { - input: [[plankWood, hopper, plankWood] - [dropper, chest, craftingPiston] - [plankWood, "oc:circuitChip1", plankWood]] -} -inventorycontrollerupgrade { - input: [[ingotGold, "oc:analyzer", ingotGold] - [dropper, "oc:circuitChip2", craftingPiston] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -signupgrade { - input: [[ingotIron, dyeBlack, ingotIron] - ["oc:circuitChip1", stickWood, "oc:circuitChip1"] - [ingotIron, craftingPiston, ingotIron]] -} -tankupgrade { - input: [[plankWood, fenceIron, plankWood] - [dropper, cauldron, craftingPiston] - [plankWood, "oc:circuitChip1", plankWood]] -} -tankcontrollerupgrade { - input: [[ingotGold, glassBottle, ingotGold] - [dropper, "oc:circuitChip2", craftingPiston] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} - -inkcartridgeempty { - input: [[iron_nugget, dropper, iron_nugget], - ["oc:materialTransistor", bucket, "oc:materialTransistor"], - [iron_nugget, "oc:materialCircuitBoardPrinted", iron_nugget]] -} - -interweb { - input: [[redstone, {block="minecraft:wool", subID=9}, redstone] - [{block="minecraft:wool", subID=9}, gemDiamond, {block="minecraft:wool", subID=9}] - [redstone, {block="minecraft:wool", subID=9}, redstone]] -} - -geolyzer { - input: [[ingotGold, compass, ingotGold] - [gemDiamond, "oc:circuitChip2", gemDiamond] - [ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]] -} -hologram2 { - input: [["oc:circuitChip3", blockGlass, "oc:circuitChip3"] - ["oc:materialCircuitBoardPrinted", blockDiamond, "oc:materialCircuitBoardPrinted"] - [obsidian, yellowDust, obsidian]] -} diff --git a/src/main/resources/assets/opencomputers/recipes/user.recipes b/src/main/resources/assets/opencomputers/recipes/user.recipes deleted file mode 100644 index 69c4632ba0..0000000000 --- a/src/main/resources/assets/opencomputers/recipes/user.recipes +++ /dev/null @@ -1,20 +0,0 @@ -# To use different sets of recipes, include other recipe files in the order of -# priority to use the recipes defined in them. The last include has the highest -# priority (i.e. included recipes simply replace the current definition for all -# already known recipes). - -# To disable a recipe, assign a boolean value to it. For example, to disable -# the recipe for the transistor: `transistor = false`. This will disable the -# recipe and hide the item in the creative tab and NEI. If you assign `true`, -# the recipe will still be disabled, but not hidden in the creative tab/NEI. - -include file("default.recipes") -#include file("hardmode.recipes") -#include file("gregtech.recipes") -#include file("peaceful.recipes") -#include file("your_custom.recipes") - -# You can also specify custom recipes in this file directly. Have a look at the -# default.recipes file to get an idea how recipes have to be structured. You'll -# want to define your recipes after all includes, to avoid those overwriting -# your recipes. \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/sounds.json b/src/main/resources/assets/opencomputers/sounds.json index 9b81c13694..727dadf9b5 100644 --- a/src/main/resources/assets/opencomputers/sounds.json +++ b/src/main/resources/assets/opencomputers/sounds.json @@ -8,36 +8,36 @@ "floppy_access": { "category": "block", "sounds": [ - "opencomputers:floppy_access1", - "opencomputers:floppy_access2", - "opencomputers:floppy_access3", - "opencomputers:floppy_access4", - "opencomputers:floppy_access5", - "opencomputers:floppy_access6" + {"name": "opencomputers:floppy_access1", "preload": true}, + {"name": "opencomputers:floppy_access2", "preload": true}, + {"name": "opencomputers:floppy_access3", "preload": true}, + {"name": "opencomputers:floppy_access4", "preload": true}, + {"name": "opencomputers:floppy_access5", "preload": true}, + {"name": "opencomputers:floppy_access6", "preload": true} ] }, "floppy_eject": { "category": "block", "sounds": [ - "opencomputers:floppy_eject" + {"name": "opencomputers:floppy_eject", "preload": true} ] }, "floppy_insert": { "category": "block", "sounds": [ - "opencomputers:floppy_insert" + {"name": "opencomputers:floppy_insert", "preload": true} ] }, "hdd_access": { "category": "block", "sounds": [ - "opencomputers:hdd_access1", - "opencomputers:hdd_access2", - "opencomputers:hdd_access3", - "opencomputers:hdd_access4", - "opencomputers:hdd_access5", - "opencomputers:hdd_access6", - "opencomputers:hdd_access7" + {"name": "opencomputers:hdd_access1", "preload": true}, + {"name": "opencomputers:hdd_access2", "preload": true}, + {"name": "opencomputers:hdd_access3", "preload": true}, + {"name": "opencomputers:hdd_access4", "preload": true}, + {"name": "opencomputers:hdd_access5", "preload": true}, + {"name": "opencomputers:hdd_access6", "preload": true}, + {"name": "opencomputers:hdd_access7", "preload": true} ] } } \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/sounds/preload.cfg b/src/main/resources/assets/opencomputers/sounds/preload.cfg deleted file mode 100644 index e7334d6c89..0000000000 --- a/src/main/resources/assets/opencomputers/sounds/preload.cfg +++ /dev/null @@ -1,16 +0,0 @@ -assets/opencomputers/sounds/computer_running.ogg -assets/opencomputers/sounds/floppy_access1.ogg -assets/opencomputers/sounds/floppy_access2.ogg -assets/opencomputers/sounds/floppy_access3.ogg -assets/opencomputers/sounds/floppy_access4.ogg -assets/opencomputers/sounds/floppy_access5.ogg -assets/opencomputers/sounds/floppy_access6.ogg -assets/opencomputers/sounds/floppy_eject.ogg -assets/opencomputers/sounds/floppy_insert.ogg -assets/opencomputers/sounds/hdd_access1.ogg -assets/opencomputers/sounds/hdd_access2.ogg -assets/opencomputers/sounds/hdd_access3.ogg -assets/opencomputers/sounds/hdd_access4.ogg -assets/opencomputers/sounds/hdd_access5.ogg -assets/opencomputers/sounds/hdd_access6.ogg -assets/opencomputers/sounds/hdd_access7.ogg \ No newline at end of file diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyeblack.png b/src/main/resources/assets/opencomputers/textures/items/floppy_black.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyeblack.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_black.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyeblue.png b/src/main/resources/assets/opencomputers/textures/items/floppy_blue.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyeblue.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_blue.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyebrown.png b/src/main/resources/assets/opencomputers/textures/items/floppy_brown.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyebrown.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_brown.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyecyan.png b/src/main/resources/assets/opencomputers/textures/items/floppy_cyan.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyecyan.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_cyan.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyegray.png b/src/main/resources/assets/opencomputers/textures/items/floppy_gray.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyegray.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_gray.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyegreen.png b/src/main/resources/assets/opencomputers/textures/items/floppy_green.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyegreen.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_green.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyelightblue.png b/src/main/resources/assets/opencomputers/textures/items/floppy_light_blue.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyelightblue.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_light_blue.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyelightgray.png b/src/main/resources/assets/opencomputers/textures/items/floppy_light_gray.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyelightgray.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_light_gray.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyelime.png b/src/main/resources/assets/opencomputers/textures/items/floppy_lime.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyelime.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_lime.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyemagenta.png b/src/main/resources/assets/opencomputers/textures/items/floppy_magenta.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyemagenta.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_magenta.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyeorange.png b/src/main/resources/assets/opencomputers/textures/items/floppy_orange.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyeorange.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_orange.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyepink.png b/src/main/resources/assets/opencomputers/textures/items/floppy_pink.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyepink.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_pink.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyepurple.png b/src/main/resources/assets/opencomputers/textures/items/floppy_purple.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyepurple.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_purple.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyered.png b/src/main/resources/assets/opencomputers/textures/items/floppy_red.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyered.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_red.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyewhite.png b/src/main/resources/assets/opencomputers/textures/items/floppy_white.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyewhite.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_white.png diff --git a/src/main/resources/assets/opencomputers/textures/items/floppy_dyeyellow.png b/src/main/resources/assets/opencomputers/textures/items/floppy_yellow.png similarity index 100% rename from src/main/resources/assets/opencomputers/textures/items/floppy_dyeyellow.png rename to src/main/resources/assets/opencomputers/textures/items/floppy_yellow.png diff --git a/src/main/resources/data/forge/tags/blocks/end_stones.json b/src/main/resources/data/forge/tags/blocks/end_stones.json new file mode 100644 index 0000000000..55c89af86e --- /dev/null +++ b/src/main/resources/data/forge/tags/blocks/end_stones.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:endstone" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/forge/tags/blocks/pistons.json b/src/main/resources/data/forge/tags/blocks/pistons.json new file mode 100644 index 0000000000..1fb4a6d786 --- /dev/null +++ b/src/main/resources/data/forge/tags/blocks/pistons.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:piston", + "minecraft:sticky_piston" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/forge/tags/items/beacon_base_blocks.json b/src/main/resources/data/forge/tags/items/beacon_base_blocks.json new file mode 100644 index 0000000000..a368aa50b6 --- /dev/null +++ b/src/main/resources/data/forge/tags/items/beacon_base_blocks.json @@ -0,0 +1,10 @@ +{ + "replace": false, + "values": [ + "minecraft:netherite_block", + "minecraft:emerald_block", + "minecraft:diamond_block", + "minecraft:gold_block", + "minecraft:iron_block" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/forge/tags/items/end_stones.json b/src/main/resources/data/forge/tags/items/end_stones.json new file mode 100644 index 0000000000..55c89af86e --- /dev/null +++ b/src/main/resources/data/forge/tags/items/end_stones.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:endstone" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/forge/tags/items/pistons.json b/src/main/resources/data/forge/tags/items/pistons.json new file mode 100644 index 0000000000..1fb4a6d786 --- /dev/null +++ b/src/main/resources/data/forge/tags/items/pistons.json @@ -0,0 +1,7 @@ +{ + "replace": false, + "values": [ + "minecraft:piston", + "minecraft:sticky_piston" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/adapter.json b/src/main/resources/data/opencomputers/loot_tables/blocks/adapter.json new file mode 100644 index 0000000000..31c6823d58 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/adapter.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:adapter" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/assembler.json b/src/main/resources/data/opencomputers/loot_tables/blocks/assembler.json new file mode 100644 index 0000000000..3a2337bd51 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/assembler.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:assembler" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/cable.json b/src/main/resources/data/opencomputers/loot_tables/blocks/cable.json new file mode 100644 index 0000000000..86950b69dd --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/cable.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "functions": [ + { + "function": "opencomputers:copy_color" + } + ], + "name": "opencomputers:cable" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/capacitor.json b/src/main/resources/data/opencomputers/loot_tables/blocks/capacitor.json new file mode 100644 index 0000000000..4a12dee16b --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/capacitor.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:capacitor" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/carpetedcapacitor.json b/src/main/resources/data/opencomputers/loot_tables/blocks/carpetedcapacitor.json new file mode 100644 index 0000000000..6e9658bbcd --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/carpetedcapacitor.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:carpetedcapacitor" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/case1.json b/src/main/resources/data/opencomputers/loot_tables/blocks/case1.json new file mode 100644 index 0000000000..0c75840b1c --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/case1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:case1" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/case2.json b/src/main/resources/data/opencomputers/loot_tables/blocks/case2.json new file mode 100644 index 0000000000..0b176c7fff --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/case2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:case2" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/case3.json b/src/main/resources/data/opencomputers/loot_tables/blocks/case3.json new file mode 100644 index 0000000000..8124f0267f --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/case3.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:case3" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/chameliumblock.json b/src/main/resources/data/opencomputers/loot_tables/blocks/chameliumblock.json new file mode 100644 index 0000000000..efec4024f1 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/chameliumblock.json @@ -0,0 +1,315 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:alternatives", + "children": [ + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "white" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 0}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "orange" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 1}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "magenta" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 2}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "light_blue" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 3}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "yellow" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 4}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "lime" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 5}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "pink" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 6}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "gray" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 7}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "light_gray" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 8}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "cyan" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 9}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "purple" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 10}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "blue" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 11}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "brown" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 12}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "green" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 13}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "conditions": [ + { + "condition": "block_state_property", + "block": "opencomputers:chameliumblock", + "properties": { + "color": "red" + } + } + ], + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 14}" + } + ], + "name": "opencomputers:chameliumblock" + }, + { + "type": "minecraft:item", + "functions": [ + { + "function": "set_nbt", + "tag": "{\"Damage\": 15}" + } + ], + "name": "opencomputers:chameliumblock" + } + ] + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/charger.json b/src/main/resources/data/opencomputers/loot_tables/blocks/charger.json new file mode 100644 index 0000000000..160cb66781 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/charger.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:charger" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/disassembler.json b/src/main/resources/data/opencomputers/loot_tables/blocks/disassembler.json new file mode 100644 index 0000000000..3f8705d01b --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/disassembler.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:disassembler" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/diskdrive.json b/src/main/resources/data/opencomputers/loot_tables/blocks/diskdrive.json new file mode 100644 index 0000000000..ba6a6807ca --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/diskdrive.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:diskdrive" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/endstone.json b/src/main/resources/data/opencomputers/loot_tables/blocks/endstone.json new file mode 100644 index 0000000000..839f84ffef --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/endstone.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:endstone" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/geolyzer.json b/src/main/resources/data/opencomputers/loot_tables/blocks/geolyzer.json new file mode 100644 index 0000000000..f011e9b434 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/geolyzer.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:geolyzer" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/hologram1.json b/src/main/resources/data/opencomputers/loot_tables/blocks/hologram1.json new file mode 100644 index 0000000000..8e5d34e7f2 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/hologram1.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:hologram1" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/hologram2.json b/src/main/resources/data/opencomputers/loot_tables/blocks/hologram2.json new file mode 100644 index 0000000000..0e0f30749d --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/hologram2.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:hologram2" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/keyboard.json b/src/main/resources/data/opencomputers/loot_tables/blocks/keyboard.json new file mode 100644 index 0000000000..df15874146 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/keyboard.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:keyboard" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/microcontroller.json b/src/main/resources/data/opencomputers/loot_tables/blocks/microcontroller.json new file mode 100644 index 0000000000..1749fc2bfb --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/microcontroller.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:item_data" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/motionsensor.json b/src/main/resources/data/opencomputers/loot_tables/blocks/motionsensor.json new file mode 100644 index 0000000000..baa71c8b2f --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/motionsensor.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:motionsensor" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/netsplitter.json b/src/main/resources/data/opencomputers/loot_tables/blocks/netsplitter.json new file mode 100644 index 0000000000..66b2d6404d --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/netsplitter.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:netsplitter" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/powerconverter.json b/src/main/resources/data/opencomputers/loot_tables/blocks/powerconverter.json new file mode 100644 index 0000000000..867418f5f1 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/powerconverter.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:powerconverter" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/powerdistributor.json b/src/main/resources/data/opencomputers/loot_tables/blocks/powerdistributor.json new file mode 100644 index 0000000000..ba25535d42 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/powerdistributor.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:powerdistributor" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/print.json b/src/main/resources/data/opencomputers/loot_tables/blocks/print.json new file mode 100644 index 0000000000..1749fc2bfb --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/print.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:item_data" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/printer.json b/src/main/resources/data/opencomputers/loot_tables/blocks/printer.json new file mode 100644 index 0000000000..81a05e0e6b --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/printer.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:printer" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/rack.json b/src/main/resources/data/opencomputers/loot_tables/blocks/rack.json new file mode 100644 index 0000000000..1fa79578fb --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/rack.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:rack" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/raid.json b/src/main/resources/data/opencomputers/loot_tables/blocks/raid.json new file mode 100644 index 0000000000..1749fc2bfb --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/raid.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:item_data" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/redstone.json b/src/main/resources/data/opencomputers/loot_tables/blocks/redstone.json new file mode 100644 index 0000000000..5bfd376475 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/redstone.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:redstone" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/relay.json b/src/main/resources/data/opencomputers/loot_tables/blocks/relay.json new file mode 100644 index 0000000000..47e2fe3750 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/relay.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:relay" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/robot.json b/src/main/resources/data/opencomputers/loot_tables/blocks/robot.json new file mode 100644 index 0000000000..e6847c1658 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/robot.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:item_data" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + }, + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:dynamic", + "name": "opencomputers:volatile_contents" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/screen1.json b/src/main/resources/data/opencomputers/loot_tables/blocks/screen1.json new file mode 100644 index 0000000000..eea4e8dbe7 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/screen1.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:screen1" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/screen2.json b/src/main/resources/data/opencomputers/loot_tables/blocks/screen2.json new file mode 100644 index 0000000000..7be03aa442 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/screen2.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:screen2" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/screen3.json b/src/main/resources/data/opencomputers/loot_tables/blocks/screen3.json new file mode 100644 index 0000000000..97e952e40c --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/screen3.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:screen3" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/transposer.json b/src/main/resources/data/opencomputers/loot_tables/blocks/transposer.json new file mode 100644 index 0000000000..891fce4664 --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/transposer.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:transposer" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/loot_tables/blocks/waypoint.json b/src/main/resources/data/opencomputers/loot_tables/blocks/waypoint.json new file mode 100644 index 0000000000..e80460addc --- /dev/null +++ b/src/main/resources/data/opencomputers/loot_tables/blocks/waypoint.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "opencomputers:waypoint" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/acid.json b/src/main/resources/data/opencomputers/recipes/acid.json new file mode 100644 index 0000000000..15b1167adf --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/acid.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:water_bucket" + }, + { + "item": "minecraft:sugar" + }, + { + "tag": "forge:slimeballs" + }, + { + "item": "minecraft:fermented_spider_eye" + }, + { + "item": "minecraft:bone" + } + ], + "result": { + "item": "opencomputers:acid" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/adapter.json b/src/main/resources/data/opencomputers/recipes/adapter.json new file mode 100644 index 0000000000..3f6d502d52 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/adapter.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ici", + "cCc", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "c": { + "tag": "opencomputers:cable" + } + }, + "result": { + "item": "opencomputers:adapter" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/alu.json b/src/main/resources/data/opencomputers/recipes/alu.json new file mode 100644 index 0000000000..d288e261e8 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/alu.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iri", + "TCT", + "iTi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "T": { + "tag": "opencomputers:materialtransistor" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:alu" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/analyzer.json b/src/main/resources/data/opencomputers/recipes/analyzer.json new file mode 100644 index 0000000000..a904121de9 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/analyzer.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "r ", + "Tg", + "Pg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "r": { + "item": "minecraft:redstone_torch" + }, + "T": { + "tag": "opencomputers:materialtransistor" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:analyzer" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/angelupgrade.json b/src/main/resources/data/opencomputers/recipes/angelupgrade.json new file mode 100644 index 0000000000..5e04b328ad --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/angelupgrade.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iei", + "CpC", + "iei" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "e": { + "tag": "forge:ender_pearls" + }, + "p": { + "item": "minecraft:sticky_piston" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:angelupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/apu1.json b/src/main/resources/data/opencomputers/recipes/apu1.json new file mode 100644 index 0000000000..46a281d246 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/apu1.json @@ -0,0 +1,28 @@ +{ + "type": "opencomputers:crafting_shaped_extended", + "pattern": [ + "gCg", + "PBG", + "gCg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:componentbus1" + }, + "P": { + "tag": "opencomputers:cpu2" + }, + "G": { + "tag": "opencomputers:graphicscard1" + } + }, + "result": { + "item": "opencomputers:apu1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/apu2.json b/src/main/resources/data/opencomputers/recipes/apu2.json new file mode 100644 index 0000000000..0c8aca229f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/apu2.json @@ -0,0 +1,28 @@ +{ + "type": "opencomputers:crafting_shaped_extended", + "pattern": [ + "dCd", + "PBG", + "dCd" + ], + "key": { + "d": { + "tag": "opencomputers:chipdiamond" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:componentbus2" + }, + "P": { + "tag": "opencomputers:cpu3" + }, + "G": { + "tag": "opencomputers:graphicscard2" + } + }, + "result": { + "item": "opencomputers:apu2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/arrowkeys.json b/src/main/resources/data/opencomputers/recipes/arrowkeys.json new file mode 100644 index 0000000000..0001b732a2 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/arrowkeys.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + " b ", + "bbb" + ], + "key": { + "b": { + "item": "minecraft:stone_button" + } + }, + "result": { + "item": "opencomputers:arrowkeys" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/assembler.json b/src/main/resources/data/opencomputers/recipes/assembler.json new file mode 100644 index 0000000000..05e98a2a5f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/assembler.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iwi", + "pCp", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "w": { + "item": "minecraft:crafting_table" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:assembler" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/batteryupgrade1.json b/src/main/resources/data/opencomputers/recipes/batteryupgrade1.json new file mode 100644 index 0000000000..54a468451e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/batteryupgrade1.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "igi", + "fCf", + "igi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "g": { + "tag": "forge:nuggets/gold" + }, + "f": { + "item": "minecraft:iron_bars" + }, + "C": { + "tag": "opencomputers:capacitor" + } + }, + "result": { + "item": "opencomputers:batteryupgrade1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/batteryupgrade2.json b/src/main/resources/data/opencomputers/recipes/batteryupgrade2.json new file mode 100644 index 0000000000..a3fa203fa6 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/batteryupgrade2.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "fgf", + "iCi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "g": { + "tag": "forge:nuggets/gold" + }, + "f": { + "item": "minecraft:iron_bars" + }, + "C": { + "tag": "opencomputers:capacitor" + } + }, + "result": { + "item": "opencomputers:batteryupgrade2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/batteryupgrade3.json b/src/main/resources/data/opencomputers/recipes/batteryupgrade3.json new file mode 100644 index 0000000000..2c8175b7d8 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/batteryupgrade3.json @@ -0,0 +1,22 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "CDC", + "iCi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "D": { + "tag": "opencomputers:chipdiamond" + }, + "C": { + "tag": "opencomputers:capacitor" + } + }, + "result": { + "item": "opencomputers:batteryupgrade3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/buttongroup.json b/src/main/resources/data/opencomputers/recipes/buttongroup.json new file mode 100644 index 0000000000..e362e8e1b7 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/buttongroup.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "bbb", + "bbb" + ], + "key": { + "b": { + "item": "minecraft:stone_button" + } + }, + "result": { + "item": "opencomputers:buttongroup" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cable.json b/src/main/resources/data/opencomputers/recipes/cable.json new file mode 100644 index 0000000000..69ac62b492 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cable.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + " i ", + "iri", + " i " + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "r": { + "tag": "forge:dusts/redstone" + } + }, + "result": { + "item": "opencomputers:cable", + "count": 4 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/capacitor.json b/src/main/resources/data/opencomputers/recipes/capacitor.json new file mode 100644 index 0000000000..da8b6f41dc --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/capacitor.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iTi", + "gpg", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:nuggets/gold" + }, + "p": { + "item": "minecraft:paper" + }, + "T": { + "tag": "opencomputers:materialtransistor" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:capacitor" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/card.json b/src/main/resources/data/opencomputers/recipes/card.json new file mode 100644 index 0000000000..e2c6cbf75b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/card.json @@ -0,0 +1,22 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "i ", + "iP", + "ig" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "g": { + "tag": "forge:nuggets/gold" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:card" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cardcontainer1.json b/src/main/resources/data/opencomputers/recipes/cardcontainer1.json new file mode 100644 index 0000000000..22af6e535d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cardcontainer1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "pc ", + "iBi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "c": { + "tag": "forge:chests" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:cardcontainer1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cardcontainer2.json b/src/main/resources/data/opencomputers/recipes/cardcontainer2.json new file mode 100644 index 0000000000..d19606d58d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cardcontainer2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "pc ", + "iBi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "c": { + "tag": "forge:chests" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:cardcontainer2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cardcontainer3.json b/src/main/resources/data/opencomputers/recipes/cardcontainer3.json new file mode 100644 index 0000000000..5b64f2e233 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cardcontainer3.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gCg", + "pc ", + "gBg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "c": { + "tag": "forge:chests" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:cardcontainer3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/carpetedcapacitor.json b/src/main/resources/data/opencomputers/recipes/carpetedcapacitor.json new file mode 100644 index 0000000000..f5558ecca6 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/carpetedcapacitor.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "opencomputers:capacitor" + }, + { + "item": "minecraft:white_carpet" + } + ], + "result": { + "item": "opencomputers:carpetedcapacitor" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/case1.json b/src/main/resources/data/opencomputers/recipes/case1.json new file mode 100644 index 0000000000..5a6a1e8403 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/case1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "bcb", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "c": { + "tag": "forge:chests" + }, + "b": { + "item": "minecraft:iron_bars" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:case1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/case2.json b/src/main/resources/data/opencomputers/recipes/case2.json new file mode 100644 index 0000000000..7b7a5d8375 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/case2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gCg", + "bcb", + "gPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "c": { + "tag": "forge:chests" + }, + "b": { + "item": "minecraft:iron_bars" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:case2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/case3.json b/src/main/resources/data/opencomputers/recipes/case3.json new file mode 100644 index 0000000000..19977cf8c3 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/case3.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "dCd", + "bcb", + "dPd" + ], + "key": { + "d": { + "tag": "forge:gems/diamond" + }, + "c": { + "tag": "forge:chests" + }, + "b": { + "item": "minecraft:iron_bars" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:case3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium.json b/src/main/resources/data/opencomputers/recipes/chamelium.json new file mode 100644 index 0000000000..142061bcca --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "grg", + "rcr", + "gwg" + ], + "key": { + "g": { + "tag": "forge:gravel" + }, + "c": { + "item": "minecraft:coal" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "w": { + "item": "minecraft:water_bucket" + } + }, + "result": { + "item": "opencomputers:chamelium", + "count": 16 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/black.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/black.json new file mode 100644 index 0000000000..97407ee4d2 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/black.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/black" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 15}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/blue.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/blue.json new file mode 100644 index 0000000000..80bd6b7d2f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/blue.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/blue" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 11}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/brown.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/brown.json new file mode 100644 index 0000000000..ab3af44cc7 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/brown.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/brown" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 12}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/cyan.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/cyan.json new file mode 100644 index 0000000000..20743e1196 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/cyan.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/cyan" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 9}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/gray.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/gray.json new file mode 100644 index 0000000000..b21b3381f4 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/gray.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/gray" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 7}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/green.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/green.json new file mode 100644 index 0000000000..346eb6f2e9 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/green.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/green" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 13}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/light_blue.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/light_blue.json new file mode 100644 index 0000000000..ab76c12891 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/light_blue.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/light_blue" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 3}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/light_gray.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/light_gray.json new file mode 100644 index 0000000000..34773f95e8 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/light_gray.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/light_gray" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 8}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/lime.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/lime.json new file mode 100644 index 0000000000..fa53032ac2 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/lime.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/lime" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 5}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/magenta.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/magenta.json new file mode 100644 index 0000000000..511d06dd7c --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/magenta.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/magenta" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 2}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/orange.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/orange.json new file mode 100644 index 0000000000..ef2f9f1acf --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/orange.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/orange" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 1}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/pink.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/pink.json new file mode 100644 index 0000000000..bc08ba163d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/pink.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/pink" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 6}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/purple.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/purple.json new file mode 100644 index 0000000000..c1e7dc7a1e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/purple.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/purple" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 10}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/red.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/red.json new file mode 100644 index 0000000000..531e3fea2f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/red.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/red" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 14}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/white.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/white.json new file mode 100644 index 0000000000..c3a17fad8a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/white.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/white" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 0}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/coloring/yellow.json b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/yellow.json new file mode 100644 index 0000000000..db4d68f66c --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/coloring/yellow.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + }, + { + "tag": "forge:dyes/yellow" + } + ], + "result": { + "item": "opencomputers:chameliumblock", + "nbt": "{\"Damage\": 4}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chamelium/splitting.json b/src/main/resources/data/opencomputers/recipes/chamelium/splitting.json new file mode 100644 index 0000000000..f482d07bf0 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chamelium/splitting.json @@ -0,0 +1,12 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:chameliumblock" + } + ], + "result": { + "item": "opencomputers:chamelium", + "count": 9 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chameliumblock.json b/src/main/resources/data/opencomputers/recipes/chameliumblock.json new file mode 100644 index 0000000000..26e10cdc9b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chameliumblock.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CCC", + "CCC", + "CCC" + ], + "key": { + "C": { + "tag": "opencomputers:chamelium" + } + }, + "result": { + "item": "opencomputers:chameliumblock", + "nbt": { + "Damage": 15 + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/charger.json b/src/main/resources/data/opencomputers/recipes/charger.json new file mode 100644 index 0000000000..53e3bf9ff4 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/charger.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "igi", + "cCc", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:ingots/gold" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "c": { + "tag": "opencomputers:capacitor" + } + }, + "result": { + "item": "opencomputers:charger" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chip1.json b/src/main/resources/data/opencomputers/recipes/chip1.json new file mode 100644 index 0000000000..bc19e69fb7 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chip1.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iii", + "rTr", + "iii" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "T": { + "tag": "opencomputers:materialtransistor" + } + }, + "result": { + "item": "opencomputers:chip1", + "count": 8 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chip2.json b/src/main/resources/data/opencomputers/recipes/chip2.json new file mode 100644 index 0000000000..46e02f835f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chip2.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ggg", + "rTr", + "ggg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "T": { + "tag": "opencomputers:materialtransistor" + } + }, + "result": { + "item": "opencomputers:chip2", + "count": 4 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chip3.json b/src/main/resources/data/opencomputers/recipes/chip3.json new file mode 100644 index 0000000000..4175689448 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chip3.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ddd", + "rTr", + "ddd" + ], + "key": { + "d": { + "tag": "opencomputers:chipdiamond" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "T": { + "tag": "opencomputers:materialtransistor" + } + }, + "result": { + "item": "opencomputers:chip3", + "count": 2 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chipdiamond.json b/src/main/resources/data/opencomputers/recipes/chipdiamond.json new file mode 100644 index 0000000000..1154a176d3 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chipdiamond.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "opencomputers:materialcuttingwire" + }, + { + "tag": "forge:gems/diamond" + } + ], + "result": { + "item": "opencomputers:chipdiamond", + "count": 6 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/chunkloaderupgrade.json b/src/main/resources/data/opencomputers/recipes/chunkloaderupgrade.json new file mode 100644 index 0000000000..79f50e7d5b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/chunkloaderupgrade.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gsg", + "CeC", + "oPo" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "s": { + "tag": "forge:glass" + }, + "o": { + "tag": "forge:obsidian" + }, + "e": { + "item": "minecraft:ender_eye" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:chunkloaderupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/colorize/cable.json b/src/main/resources/data/opencomputers/recipes/colorize/cable.json new file mode 100644 index 0000000000..ea91e59f72 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/colorize/cable.json @@ -0,0 +1,4 @@ +{ + "type": "opencomputers:crafting_colorize", + "item": "opencomputers:cable" +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/colorize/hoverboots.json b/src/main/resources/data/opencomputers/recipes/colorize/hoverboots.json new file mode 100644 index 0000000000..973455979f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/colorize/hoverboots.json @@ -0,0 +1,4 @@ +{ + "type": "opencomputers:crafting_colorize", + "item": "opencomputers:hoverboots" +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/componentbus1.json b/src/main/resources/data/opencomputers/recipes/componentbus1.json new file mode 100644 index 0000000000..d1dd337f6f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/componentbus1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iri", + "CU ", + "iPi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "U": { + "tag": "opencomputers:materialcu" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:componentbus1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/componentbus2.json b/src/main/resources/data/opencomputers/recipes/componentbus2.json new file mode 100644 index 0000000000..9170c64a42 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/componentbus2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "grg", + "CU ", + "gPg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "U": { + "tag": "opencomputers:materialcu" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:componentbus2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/componentbus3.json b/src/main/resources/data/opencomputers/recipes/componentbus3.json new file mode 100644 index 0000000000..d66b7019fc --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/componentbus3.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "drd", + "CU ", + "dPd" + ], + "key": { + "d": { + "tag": "opencomputers:chipdiamond" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "U": { + "tag": "opencomputers:materialcu" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:componentbus3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cpu1.json b/src/main/resources/data/opencomputers/recipes/cpu1.json new file mode 100644 index 0000000000..ff8fce0e20 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cpu1.json @@ -0,0 +1,28 @@ +{ + "type": "opencomputers:crafting_shaped_extended", + "pattern": [ + "iri", + "CUC", + "iAi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "U": { + "tag": "opencomputers:materialcu" + }, + "A": { + "tag": "opencomputers:materialalu" + } + }, + "result": { + "item": "opencomputers:cpu1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cpu2.json b/src/main/resources/data/opencomputers/recipes/cpu2.json new file mode 100644 index 0000000000..b829c63c3a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cpu2.json @@ -0,0 +1,28 @@ +{ + "type": "opencomputers:crafting_shaped_extended", + "pattern": [ + "grg", + "CUC", + "gAg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "U": { + "tag": "opencomputers:materialcu" + }, + "A": { + "tag": "opencomputers:materialalu" + } + }, + "result": { + "item": "opencomputers:cpu2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cpu3.json b/src/main/resources/data/opencomputers/recipes/cpu3.json new file mode 100644 index 0000000000..20c11e9956 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cpu3.json @@ -0,0 +1,28 @@ +{ + "type": "opencomputers:crafting_shaped_extended", + "pattern": [ + "drd", + "CUC", + "dAd" + ], + "key": { + "d": { + "tag": "opencomputers:chipdiamond" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "U": { + "tag": "opencomputers:materialcu" + }, + "A": { + "tag": "opencomputers:materialalu" + } + }, + "result": { + "item": "opencomputers:cpu3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/craftingupgrade.json b/src/main/resources/data/opencomputers/recipes/craftingupgrade.json new file mode 100644 index 0000000000..cafa5ae156 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/craftingupgrade.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "i i", + "CwC", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "w": { + "item": "minecraft:crafting_table" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:craftingupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cu.json b/src/main/resources/data/opencomputers/recipes/cu.json new file mode 100644 index 0000000000..d12240688b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cu.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "grg", + "TcT", + "gTg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "c": { + "item": "minecraft:clock" + }, + "T": { + "tag": "opencomputers:materialtransistor" + } + }, + "result": { + "item": "opencomputers:cu" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/cuttingwire.json b/src/main/resources/data/opencomputers/recipes/cuttingwire.json new file mode 100644 index 0000000000..343093c2e9 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/cuttingwire.json @@ -0,0 +1,17 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "sis" + ], + "key": { + "s": { + "tag": "forge:rods/wooden" + }, + "i": { + "tag": "forge:nuggets/iron" + } + }, + "result": { + "item": "opencomputers:cuttingwire" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/databaseupgrade1.json b/src/main/resources/data/opencomputers/recipes/databaseupgrade1.json new file mode 100644 index 0000000000..f23b93b915 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/databaseupgrade1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iAi", + "CHC", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "A": { + "tag": "opencomputers:analyzer" + }, + "H": { + "tag": "opencomputers:hdd1" + } + }, + "result": { + "item": "opencomputers:databaseupgrade1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/databaseupgrade2.json b/src/main/resources/data/opencomputers/recipes/databaseupgrade2.json new file mode 100644 index 0000000000..c6576ea95d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/databaseupgrade2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iAi", + "CHC", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "A": { + "tag": "opencomputers:analyzer" + }, + "H": { + "tag": "opencomputers:hdd2" + } + }, + "result": { + "item": "opencomputers:databaseupgrade2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/databaseupgrade3.json b/src/main/resources/data/opencomputers/recipes/databaseupgrade3.json new file mode 100644 index 0000000000..4a194ba8dc --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/databaseupgrade3.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iAi", + "CHC", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "A": { + "tag": "opencomputers:analyzer" + }, + "H": { + "tag": "opencomputers:hdd3" + } + }, + "result": { + "item": "opencomputers:databaseupgrade3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/datacard1.json b/src/main/resources/data/opencomputers/recipes/datacard1.json new file mode 100644 index 0000000000..9c3eb403ef --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/datacard1.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iAC", + " B " + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:materialcard" + }, + "A": { + "tag": "opencomputers:materialalu" + } + }, + "result": { + "item": "opencomputers:datacard1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/datacard2.json b/src/main/resources/data/opencomputers/recipes/datacard2.json new file mode 100644 index 0000000000..f76d6038ff --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/datacard2.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gPC", + " B " + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "B": { + "tag": "opencomputers:materialcard" + }, + "P": { + "tag": "opencomputers:cpu1" + } + }, + "result": { + "item": "opencomputers:datacard2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/datacard3.json b/src/main/resources/data/opencomputers/recipes/datacard3.json new file mode 100644 index 0000000000..f6cda2b60f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/datacard3.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "dPM", + " B " + ], + "key": { + "d": { + "tag": "opencomputers:chipdiamond" + }, + "B": { + "tag": "opencomputers:materialcard" + }, + "M": { + "tag": "opencomputers:ram5" + }, + "P": { + "tag": "opencomputers:cpu2" + } + }, + "result": { + "item": "opencomputers:datacard3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/decolorize/cable.json b/src/main/resources/data/opencomputers/recipes/decolorize/cable.json new file mode 100644 index 0000000000..61a33288e6 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/decolorize/cable.json @@ -0,0 +1,4 @@ +{ + "type": "opencomputers:crafting_decolorize", + "item": "opencomputers:cable" +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/decolorize/hoverboots.json b/src/main/resources/data/opencomputers/recipes/decolorize/hoverboots.json new file mode 100644 index 0000000000..ba63396e0b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/decolorize/hoverboots.json @@ -0,0 +1,4 @@ +{ + "type": "opencomputers:crafting_decolorize", + "item": "opencomputers:hoverboots" +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/disassembler.json b/src/main/resources/data/opencomputers/recipes/disassembler.json new file mode 100644 index 0000000000..41d0a8e3cc --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/disassembler.json @@ -0,0 +1,34 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "UgA", + "p o", + "ili" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:glass_panes" + }, + "l": { + "item": "minecraft:lava_bucket" + }, + "o": { + "tag": "forge:obsidian" + }, + "p": { + "tag": "forge:pistons" + }, + "U": { + "tag": "opencomputers:materialcu" + }, + "A": { + "tag": "opencomputers:analyzer" + } + }, + "result": { + "item": "opencomputers:disassembler" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/disk.json b/src/main/resources/data/opencomputers/recipes/disk.json new file mode 100644 index 0000000000..ae74390769 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/disk.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + " i ", + "i i", + " i " + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + } + }, + "result": { + "item": "opencomputers:disk" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/diskdrive.json b/src/main/resources/data/opencomputers/recipes/diskdrive.json new file mode 100644 index 0000000000..4049801bab --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/diskdrive.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "ps ", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "s": { + "tag": "forge:rods/wooden" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:diskdrive" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/diskdrivemountable.json b/src/main/resources/data/opencomputers/recipes/diskdrivemountable.json new file mode 100644 index 0000000000..58689b43bb --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/diskdrivemountable.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "oCo", + "fDf", + "oPo" + ], + "key": { + "o": { + "tag": "forge:obsidian" + }, + "f": { + "item": "minecraft:iron_bars" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "D": { + "tag": "opencomputers:diskdrive" + } + }, + "result": { + "item": "opencomputers:diskdrivemountable" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/dronecase1.json b/src/main/resources/data/opencomputers/recipes/dronecase1.json new file mode 100644 index 0000000000..bd37834b2f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/dronecase1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "EcE", + "CMC", + "EBE" + ], + "key": { + "c": { + "item": "minecraft:compass" + }, + "E": { + "tag": "forge:end_stones" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:componentbus2" + }, + "M": { + "tag": "opencomputers:microcontrollercase1" + } + }, + "result": { + "item": "opencomputers:dronecase1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/dronecase2.json b/src/main/resources/data/opencomputers/recipes/dronecase2.json new file mode 100644 index 0000000000..47e5ed298e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/dronecase2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "EcE", + "CMC", + "EBE" + ], + "key": { + "c": { + "item": "minecraft:compass" + }, + "E": { + "tag": "forge:end_stones" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:componentbus3" + }, + "M": { + "tag": "opencomputers:microcontrollercase2" + } + }, + "result": { + "item": "opencomputers:dronecase2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/eeprom.json b/src/main/resources/data/opencomputers/recipes/eeprom.json new file mode 100644 index 0000000000..9b8572103a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/eeprom.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gTg", + "pCp", + "grg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "p": { + "item": "minecraft:paper" + }, + "r": { + "item": "minecraft:redstone_torch" + }, + "T": { + "tag": "opencomputers:materialtransistor" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:eeprom" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/eeprom/copying.json b/src/main/resources/data/opencomputers/recipes/eeprom/copying.json new file mode 100644 index 0000000000..18df60cb9c --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/eeprom/copying.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:eeprom" + }, + { + "item": "opencomputers:eeprom" + } + ], + "result": { + "item": "opencomputers:eeprom", + "count": 2 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/eeprom/formatting.json b/src/main/resources/data/opencomputers/recipes/eeprom/formatting.json new file mode 100644 index 0000000000..9753bd3e30 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/eeprom/formatting.json @@ -0,0 +1,11 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:eeprom" + } + ], + "result": { + "item": "opencomputers:eeprom" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/endstone.json b/src/main/resources/data/opencomputers/recipes/endstone.json new file mode 100644 index 0000000000..0d872c3c48 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/endstone.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "eCe", + "CeC", + "eCe" + ], + "key": { + "e": { + "tag": "forge:ender_pearls" + }, + "C": { + "tag": "opencomputers:chameliumblock" + } + }, + "result": { + "item": "opencomputers:endstone" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/experienceupgrade.json b/src/main/resources/data/opencomputers/recipes/experienceupgrade.json new file mode 100644 index 0000000000..136f7e3030 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/experienceupgrade.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "g g", + "CeC", + "gPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "e": { + "tag": "forge:gems/emerald" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:experienceupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy.json b/src/main/resources/data/opencomputers/recipes/floppy.json new file mode 100644 index 0000000000..72c332f673 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ili", + "pDp", + "ipi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "p": { + "item": "minecraft:paper" + }, + "l": { + "item": "minecraft:lever" + }, + "D": { + "tag": "opencomputers:materialdisk" + } + }, + "result": { + "item": "opencomputers:floppy", + "nbt": { + "oc:color": 8 + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/black.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/black.json new file mode 100644 index 0000000000..53ef4be93d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/black.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/black" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 15}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/blue.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/blue.json new file mode 100644 index 0000000000..bc56769cc8 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/blue.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/blue" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 11}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/brown.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/brown.json new file mode 100644 index 0000000000..dca6215ef2 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/brown.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/brown" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 12}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/cyan.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/cyan.json new file mode 100644 index 0000000000..03fe66029a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/cyan.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/cyan" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 9}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/gray.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/gray.json new file mode 100644 index 0000000000..80749c1616 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/gray.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/gray" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 7}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/green.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/green.json new file mode 100644 index 0000000000..c1923cde86 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/green.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/green" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 13}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/light_blue.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/light_blue.json new file mode 100644 index 0000000000..d70ede156b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/light_blue.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/light_blue" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 3}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/light_gray.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/light_gray.json new file mode 100644 index 0000000000..c754fbc926 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/light_gray.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/light_gray" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 8}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/lime.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/lime.json new file mode 100644 index 0000000000..cc6234e310 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/lime.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/lime" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 5}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/magenta.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/magenta.json new file mode 100644 index 0000000000..594f55833a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/magenta.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/magenta" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 2}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/orange.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/orange.json new file mode 100644 index 0000000000..1f14c00dd8 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/orange.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/orange" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 1}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/pink.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/pink.json new file mode 100644 index 0000000000..b019825ebc --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/pink.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/pink" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 6}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/purple.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/purple.json new file mode 100644 index 0000000000..a6940ee66d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/purple.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/purple" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 10}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/red.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/red.json new file mode 100644 index 0000000000..23680d120b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/red.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/red" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 14}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/white.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/white.json new file mode 100644 index 0000000000..4040d59402 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/white.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/white" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 0}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/coloring/yellow.json b/src/main/resources/data/opencomputers/recipes/floppy/coloring/yellow.json new file mode 100644 index 0000000000..5472ebd757 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/coloring/yellow.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + }, + { + "tag": "forge:dyes/yellow" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": "{\"oc:color\": 4}" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/floppy/formatting.json b/src/main/resources/data/opencomputers/recipes/floppy/formatting.json new file mode 100644 index 0000000000..0358f3a9d2 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/floppy/formatting.json @@ -0,0 +1,11 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:floppy" + } + ], + "result": { + "item": "opencomputers:floppy" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/generatorupgrade.json b/src/main/resources/data/opencomputers/recipes/generatorupgrade.json new file mode 100644 index 0000000000..d367d0d843 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/generatorupgrade.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "i i", + "CpC", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:generatorupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/geolyzer.json b/src/main/resources/data/opencomputers/recipes/geolyzer.json new file mode 100644 index 0000000000..e7899a2e4f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/geolyzer.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gcg", + "eCe", + "gPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "c": { + "item": "minecraft:compass" + }, + "e": { + "item": "minecraft:ender_eye" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:geolyzer" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/graphicscard1.json b/src/main/resources/data/opencomputers/recipes/graphicscard1.json new file mode 100644 index 0000000000..9ca3f647f6 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/graphicscard1.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CAM", + " B " + ], + "key": { + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:materialcard" + }, + "A": { + "tag": "opencomputers:materialalu" + }, + "M": { + "tag": "opencomputers:ram1" + } + }, + "result": { + "item": "opencomputers:graphicscard1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/graphicscard2.json b/src/main/resources/data/opencomputers/recipes/graphicscard2.json new file mode 100644 index 0000000000..0689f0ee3e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/graphicscard2.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CAM", + " B " + ], + "key": { + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:materialcard" + }, + "A": { + "tag": "opencomputers:materialalu" + }, + "M": { + "tag": "opencomputers:ram3" + } + }, + "result": { + "item": "opencomputers:graphicscard2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/graphicscard3.json b/src/main/resources/data/opencomputers/recipes/graphicscard3.json new file mode 100644 index 0000000000..f47935e0db --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/graphicscard3.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CAM", + " B " + ], + "key": { + "C": { + "tag": "opencomputers:circuitchip3" + }, + "B": { + "tag": "opencomputers:materialcard" + }, + "A": { + "tag": "opencomputers:materialalu" + }, + "M": { + "tag": "opencomputers:ram5" + } + }, + "result": { + "item": "opencomputers:graphicscard3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hdd/formatting1.json b/src/main/resources/data/opencomputers/recipes/hdd/formatting1.json new file mode 100644 index 0000000000..42a71dbf08 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hdd/formatting1.json @@ -0,0 +1,11 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:hdd1" + } + ], + "result": { + "item": "opencomputers:hdd1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hdd/formatting2.json b/src/main/resources/data/opencomputers/recipes/hdd/formatting2.json new file mode 100644 index 0000000000..647faaecfb --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hdd/formatting2.json @@ -0,0 +1,11 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:hdd2" + } + ], + "result": { + "item": "opencomputers:hdd2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hdd/formatting3.json b/src/main/resources/data/opencomputers/recipes/hdd/formatting3.json new file mode 100644 index 0000000000..6907530501 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hdd/formatting3.json @@ -0,0 +1,11 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:hdd3" + } + ], + "result": { + "item": "opencomputers:hdd3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hdd1.json b/src/main/resources/data/opencomputers/recipes/hdd1.json new file mode 100644 index 0000000000..1a4848e4ed --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hdd1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CDi", + "PDp", + "CDi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "p": { + "tag": "forge:pistons" + }, + "D": { + "tag": "opencomputers:materialdisk" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:hdd1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hdd2.json b/src/main/resources/data/opencomputers/recipes/hdd2.json new file mode 100644 index 0000000000..bb91754de5 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hdd2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CDg", + "PDp", + "CDg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "p": { + "tag": "forge:pistons" + }, + "D": { + "tag": "opencomputers:materialdisk" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "C": { + "tag": "opencomputers:circuitchip2" + } + }, + "result": { + "item": "opencomputers:hdd2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hdd3.json b/src/main/resources/data/opencomputers/recipes/hdd3.json new file mode 100644 index 0000000000..2e552d2487 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hdd3.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CDd", + "PDp", + "CDd" + ], + "key": { + "d": { + "tag": "forge:gems/diamond" + }, + "p": { + "tag": "forge:pistons" + }, + "D": { + "tag": "opencomputers:materialdisk" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "C": { + "tag": "opencomputers:circuitchip3" + } + }, + "result": { + "item": "opencomputers:hdd3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hologram1.json b/src/main/resources/data/opencomputers/recipes/hologram1.json new file mode 100644 index 0000000000..051ad335e9 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hologram1.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CgC", + "PdP", + "oGo" + ], + "key": { + "d": { + "tag": "opencomputers:chipdiamond" + }, + "g": { + "tag": "forge:glass_panes" + }, + "o": { + "tag": "forge:obsidian" + }, + "G": { + "tag": "forge:dusts/glowstone" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:hologram1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hologram2.json b/src/main/resources/data/opencomputers/recipes/hologram2.json new file mode 100644 index 0000000000..9874b8967b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hologram2.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CgC", + "PdP", + "obo" + ], + "key": { + "d": { + "tag": "forge:gems/diamond" + }, + "g": { + "tag": "forge:glass" + }, + "o": { + "tag": "forge:obsidian" + }, + "b": { + "item": "minecraft:blaze_powder" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:hologram2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hoverboots.json b/src/main/resources/data/opencomputers/recipes/hoverboots.json new file mode 100644 index 0000000000..5fe0b7addd --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hoverboots.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iHi", + "LDL", + "iCi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "L": { + "tag": "forge:leather" + }, + "C": { + "tag": "opencomputers:capacitor" + }, + "D": { + "tag": "opencomputers:dronecase1" + }, + "H": { + "tag": "opencomputers:hoverupgrade2" + } + }, + "result": { + "item": "opencomputers:hoverboots" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hoverupgrade1.json b/src/main/resources/data/opencomputers/recipes/hoverupgrade1.json new file mode 100644 index 0000000000..c38ca51e02 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hoverupgrade1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "fCf", + "ili", + "fPf" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "f": { + "tag": "forge:feathers" + }, + "l": { + "tag": "forge:leather" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:hoverupgrade1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/hoverupgrade2.json b/src/main/resources/data/opencomputers/recipes/hoverupgrade2.json new file mode 100644 index 0000000000..4546f46371 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/hoverupgrade2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "eCe", + "gig", + "ePe" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:nuggets/gold" + }, + "e": { + "tag": "forge:end_stones" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:hoverupgrade2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/inkcartridge.json b/src/main/resources/data/opencomputers/recipes/inkcartridge.json new file mode 100644 index 0000000000..655c4a619a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/inkcartridge.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "opencomputers:inkcartridgeempty" + }, + { + "tag": "forge:dyes/cyan" + }, + { + "tag": "forge:dyes/magenta" + }, + { + "tag": "forge:dyes/yellow" + }, + { + "tag": "forge:dyes/black" + } + ], + "result": { + "item": "opencomputers:inkcartridge" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/inkcartridgeempty.json b/src/main/resources/data/opencomputers/recipes/inkcartridgeempty.json new file mode 100644 index 0000000000..f05081ba5c --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/inkcartridgeempty.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "idi", + "TbT", + "iPi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "b": { + "item": "minecraft:bucket" + }, + "d": { + "item": "minecraft:dispenser" + }, + "T": { + "tag": "opencomputers:materialtransistor" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:inkcartridgeempty" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/internetcard.json b/src/main/resources/data/opencomputers/recipes/internetcard.json new file mode 100644 index 0000000000..bc91064094 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/internetcard.json @@ -0,0 +1,27 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ICr", + " Bo" + ], + "key": { + "r": { + "item": "minecraft:redstone_torch" + }, + "o": { + "tag": "forge:obsidian" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "I": { + "tag": "opencomputers:materialinterweb" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:internetcard" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/interweb.json b/src/main/resources/data/opencomputers/recipes/interweb.json new file mode 100644 index 0000000000..75cd6112ff --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/interweb.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "sss", + "ses", + "sss" + ], + "key": { + "s": { + "tag": "forge:string" + }, + "e": { + "tag": "forge:ender_pearls" + } + }, + "result": { + "item": "opencomputers:interweb" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/inventorycontrollerupgrade.json b/src/main/resources/data/opencomputers/recipes/inventorycontrollerupgrade.json new file mode 100644 index 0000000000..abc5d11cea --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/inventorycontrollerupgrade.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gAg", + "dCp", + "gPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "d": { + "item": "minecraft:dropper" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "A": { + "tag": "opencomputers:analyzer" + } + }, + "result": { + "item": "opencomputers:inventorycontrollerupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/inventoryupgrade.json b/src/main/resources/data/opencomputers/recipes/inventoryupgrade.json new file mode 100644 index 0000000000..89dac6713b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/inventoryupgrade.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "whw", + "dcp", + "wCw" + ], + "key": { + "w": { + "tag": "minecraft:planks" + }, + "c": { + "tag": "forge:chests" + }, + "h": { + "item": "minecraft:hopper" + }, + "d": { + "item": "minecraft:dropper" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:inventoryupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/keyboard.json b/src/main/resources/data/opencomputers/recipes/keyboard.json new file mode 100644 index 0000000000..d84354246e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/keyboard.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "BBB", + "BAN" + ], + "key": { + "B": { + "tag": "opencomputers:materialbuttongroup" + }, + "A": { + "tag": "opencomputers:materialarrowkey" + }, + "N": { + "tag": "opencomputers:materialnumpad" + } + }, + "result": { + "item": "opencomputers:keyboard" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/lancard.json b/src/main/resources/data/opencomputers/recipes/lancard.json new file mode 100644 index 0000000000..c05ba47d6d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/lancard.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "cC", + " B" + ], + "key": { + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:materialcard" + }, + "c": { + "tag": "opencomputers:cable" + } + }, + "result": { + "item": "opencomputers:lancard" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/leashupgrade.json b/src/main/resources/data/opencomputers/recipes/leashupgrade.json new file mode 100644 index 0000000000..f6961c829a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/leashupgrade.json @@ -0,0 +1,22 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ili", + "lCl", + "ili" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "l": { + "item": "minecraft:lead" + }, + "C": { + "tag": "opencomputers:materialcu" + } + }, + "result": { + "item": "opencomputers:leashupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/linkedcard.json b/src/main/resources/data/opencomputers/recipes/linkedcard.json new file mode 100644 index 0000000000..4726421fb8 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/linkedcard.json @@ -0,0 +1,26 @@ +{ + "type": "opencomputers:crafting_shaped_extended", + "pattern": [ + "e e", + "LIL", + "C C" + ], + "key": { + "e": { + "item": "minecraft:ender_eye" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "I": { + "tag": "opencomputers:materialinterweb" + }, + "L": { + "tag": "opencomputers:lancard" + } + }, + "result": { + "item": "opencomputers:linkedcard", + "count": 2 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/lootdisks/cycling.json b/src/main/resources/data/opencomputers/recipes/lootdisks/cycling.json new file mode 100644 index 0000000000..61e59a9a0b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/lootdisks/cycling.json @@ -0,0 +1,3 @@ +{ + "type": "opencomputers:crafting_lootdisk_cycling" +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/lootdisks/openos.json b/src/main/resources/data/opencomputers/recipes/lootdisks/openos.json new file mode 100644 index 0000000000..5538f43146 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/lootdisks/openos.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "opencomputers:floppy" + }, + { + "tag": "opencomputers:manual" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": { + "oc:data": { + "oc:fs.label": "openos" + }, + "oc:lootFactory": "opencomputers:openos", + "oc:color": 13, + "display": { + "Name": "OpenOS (Operating System)" + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/lootdisks/oppm.json b/src/main/resources/data/opencomputers/recipes/lootdisks/oppm.json new file mode 100644 index 0000000000..cc90e6462d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/lootdisks/oppm.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "opencomputers:floppy" + }, + { + "tag": "opencomputers:materialinterweb" + } + ], + "result": { + "item": "opencomputers:floppy", + "nbt": { + "oc:data": { + "oc:fs.label": "oppm" + }, + "oc:lootFactory": "opencomputers:oppm", + "oc:color": 9, + "display": { + "Name": "OPPM (Package Manager)" + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/manual.json b/src/main/resources/data/opencomputers/recipes/manual.json new file mode 100644 index 0000000000..0e9ace7902 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/manual.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "item": "minecraft:book" + }, + { + "tag": "opencomputers:circuitchip1" + } + ], + "result": { + "item": "opencomputers:manual" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/mfu.json b/src/main/resources/data/opencomputers/recipes/mfu.json new file mode 100644 index 0000000000..38fc731b06 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/mfu.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "clc", + "LAL", + "clc" + ], + "key": { + "l": { + "tag": "forge:gems/lapis" + }, + "c": { + "tag": "opencomputers:chamelium" + }, + "A": { + "tag": "opencomputers:adapter" + }, + "L": { + "tag": "opencomputers:linkedcard" + } + }, + "result": { + "item": "opencomputers:mfu" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/microcontrollercase1.json b/src/main/resources/data/opencomputers/recipes/microcontrollercase1.json new file mode 100644 index 0000000000..8677c74faf --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/microcontrollercase1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "rcr", + "iPi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "c": { + "tag": "forge:chests" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:microcontrollercase1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/microcontrollercase2.json b/src/main/resources/data/opencomputers/recipes/microcontrollercase2.json new file mode 100644 index 0000000000..48e014f315 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/microcontrollercase2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gCg", + "rcr", + "gPg" + ], + "key": { + "g": { + "tag": "forge:nuggets/gold" + }, + "r": { + "tag": "forge:storage_blocks/redstone" + }, + "c": { + "tag": "forge:chests" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:microcontrollercase2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/motionsensor.json b/src/main/resources/data/opencomputers/recipes/motionsensor.json new file mode 100644 index 0000000000..213b73a3b1 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/motionsensor.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gdg", + "dCd", + "gPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "d": { + "item": "minecraft:daylight_detector" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "C": { + "tag": "opencomputers:cpu2" + } + }, + "result": { + "item": "opencomputers:motionsensor" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/nanomachines.json b/src/main/resources/data/opencomputers/recipes/nanomachines.json new file mode 100644 index 0000000000..ab356d004d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/nanomachines.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "SRS", + "PAM", + "SCS" + ], + "key": { + "S": { + "tag": "opencomputers:chamelium" + }, + "A": { + "tag": "opencomputers:materialacid" + }, + "C": { + "tag": "opencomputers:capacitor" + }, + "R": { + "tag": "opencomputers:wlancard2" + }, + "M": { + "tag": "opencomputers:ram1" + }, + "P": { + "tag": "opencomputers:cpu2" + } + }, + "result": { + "item": "opencomputers:nanomachines" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/navigationupgrade.json b/src/main/resources/data/opencomputers/recipes/navigationupgrade.json new file mode 100644 index 0000000000..4281e79c26 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/navigationupgrade.json @@ -0,0 +1,28 @@ +{ + "type": "opencomputers:crafting_shaped_extended", + "pattern": [ + "gcg", + "CmC", + "gpg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "c": { + "item": "minecraft:compass" + }, + "m": { + "item": "minecraft:filled_map" + }, + "p": { + "item": "minecraft:potion" + }, + "C": { + "tag": "opencomputers:circuitchip2" + } + }, + "result": { + "item": "opencomputers:navigationupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/netsplitter.json b/src/main/resources/data/opencomputers/recipes/netsplitter.json new file mode 100644 index 0000000000..16e9330a7a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/netsplitter.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ici", + "cpc", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "p": { + "tag": "forge:pistons" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "c": { + "tag": "opencomputers:cable" + } + }, + "result": { + "item": "opencomputers:netsplitter" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/numpad.json b/src/main/resources/data/opencomputers/recipes/numpad.json new file mode 100644 index 0000000000..82aef08dcf --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/numpad.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "bbb", + "bbb", + "bbb" + ], + "key": { + "b": { + "item": "minecraft:stone_button" + } + }, + "result": { + "item": "opencomputers:numpad" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/pistonupgrade.json b/src/main/resources/data/opencomputers/recipes/pistonupgrade.json new file mode 100644 index 0000000000..84ef4b78de --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/pistonupgrade.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ipi", + "sCs", + "iPi" + ], + "key": { + "s": { + "tag": "forge:rods/wooden" + }, + "i": { + "tag": "forge:ingots/iron" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:pistonupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/powerconverter.json b/src/main/resources/data/opencomputers/recipes/powerconverter.json new file mode 100644 index 0000000000..4d8d4ebec2 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/powerconverter.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ici", + "gCg", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:ingots/gold" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "c": { + "tag": "opencomputers:cable" + } + }, + "result": { + "item": "opencomputers:powerconverter" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/powerdistributor.json b/src/main/resources/data/opencomputers/recipes/powerdistributor.json new file mode 100644 index 0000000000..eacc393044 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/powerdistributor.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "igi", + "cCc", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:ingots/gold" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "c": { + "tag": "opencomputers:cable" + } + }, + "result": { + "item": "opencomputers:powerdistributor" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/print/beacon.json b/src/main/resources/data/opencomputers/recipes/print/beacon.json new file mode 100644 index 0000000000..e9ea88d3da --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/print/beacon.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:print" + }, + { + "tag": "forge:beacon_base_blocks" + } + ], + "result": { + "item": "opencomputers:print" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/print/glowstone.json b/src/main/resources/data/opencomputers/recipes/print/glowstone.json new file mode 100644 index 0000000000..0e3d021bf0 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/print/glowstone.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:print" + }, + { + "item": "minecraft:glowstone" + } + ], + "result": { + "item": "opencomputers:print" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/print/glowstone_dust.json b/src/main/resources/data/opencomputers/recipes/print/glowstone_dust.json new file mode 100644 index 0000000000..70668225ed --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/print/glowstone_dust.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:print" + }, + { + "tag": "forge:dusts/glowstone" + } + ], + "result": { + "item": "opencomputers:print" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/printedcircuitboard.json b/src/main/resources/data/opencomputers/recipes/printedcircuitboard.json new file mode 100644 index 0000000000..907b0d4052 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/printedcircuitboard.json @@ -0,0 +1,9 @@ +{ + "type": "minecraft:smelting", + "ingredient": { + "tag": "opencomputers:materialcircuitboardraw" + }, + "result": "opencomputers:printedcircuitboard", + "experience": 0.1, + "cookingtime": 200 +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/printer.json b/src/main/resources/data/opencomputers/recipes/printer.json new file mode 100644 index 0000000000..8b689d686a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/printer.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ihi", + "pCp", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "h": { + "item": "minecraft:hopper" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:printer" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/rack.json b/src/main/resources/data/opencomputers/recipes/rack.json new file mode 100644 index 0000000000..76759006ee --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/rack.json @@ -0,0 +1,34 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "dWd", + "bcb", + "RPD" + ], + "key": { + "d": { + "tag": "forge:gems/diamond" + }, + "c": { + "tag": "forge:chests" + }, + "b": { + "item": "minecraft:iron_bars" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "W": { + "tag": "opencomputers:wlancard2" + }, + "R": { + "tag": "opencomputers:relay" + }, + "D": { + "tag": "opencomputers:powerdistributor" + } + }, + "result": { + "item": "opencomputers:rack" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/raid.json b/src/main/resources/data/opencomputers/recipes/raid.json new file mode 100644 index 0000000000..41cf6e7da7 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/raid.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iPi", + "MDM", + "iCi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "M": { + "tag": "opencomputers:ram1" + }, + "P": { + "tag": "opencomputers:cpu3" + }, + "D": { + "tag": "opencomputers:diskdrive" + } + }, + "result": { + "item": "opencomputers:raid" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/ram1.json b/src/main/resources/data/opencomputers/recipes/ram1.json new file mode 100644 index 0000000000..86e31a3858 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/ram1.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "cic", + " P " + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "c": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:ram1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/ram2.json b/src/main/resources/data/opencomputers/recipes/ram2.json new file mode 100644 index 0000000000..28bea65d17 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/ram2.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "cCc", + " P " + ], + "key": { + "c": { + "tag": "opencomputers:circuitchip1" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:ram2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/ram3.json b/src/main/resources/data/opencomputers/recipes/ram3.json new file mode 100644 index 0000000000..b13d00989b --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/ram3.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "cic", + " P " + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "c": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:ram3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/ram4.json b/src/main/resources/data/opencomputers/recipes/ram4.json new file mode 100644 index 0000000000..b7a25de2d3 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/ram4.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "cCc", + " P " + ], + "key": { + "c": { + "tag": "opencomputers:circuitchip2" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:ram4" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/ram5.json b/src/main/resources/data/opencomputers/recipes/ram5.json new file mode 100644 index 0000000000..11447a4a1e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/ram5.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "cic", + " P " + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "c": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:ram5" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/ram6.json b/src/main/resources/data/opencomputers/recipes/ram6.json new file mode 100644 index 0000000000..dae767c322 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/ram6.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "CCC", + "cPc" + ], + "key": { + "c": { + "tag": "opencomputers:circuitchip2" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:ram6" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/rawcircuitboard.json b/src/main/resources/data/opencomputers/recipes/rawcircuitboard.json new file mode 100644 index 0000000000..0d4c7e7ac5 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/rawcircuitboard.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "forge:ingots/gold" + }, + { + "item": "minecraft:clay" + }, + { + "tag": "forge:dyes/green" + } + ], + "result": { + "item": "opencomputers:rawcircuitboard", + "count": 8 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/recrafting/drone.json b/src/main/resources/data/opencomputers/recipes/recrafting/drone.json new file mode 100644 index 0000000000..a604c4e431 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/recrafting/drone.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:drone" + }, + { + "item": "opencomputers:eeprom" + } + ], + "result": { + "item": "opencomputers:drone" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/recrafting/linkedcard.json b/src/main/resources/data/opencomputers/recipes/recrafting/linkedcard.json new file mode 100644 index 0000000000..b30816050d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/recrafting/linkedcard.json @@ -0,0 +1,15 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:linkedcard" + }, + { + "item": "opencomputers:linkedcard" + } + ], + "result": { + "item": "opencomputers:linkedcard", + "count": 2 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/recrafting/microcontroller.json b/src/main/resources/data/opencomputers/recipes/recrafting/microcontroller.json new file mode 100644 index 0000000000..bd0127450a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/recrafting/microcontroller.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:microcontroller" + }, + { + "item": "opencomputers:eeprom" + } + ], + "result": { + "item": "opencomputers:microcontroller" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/recrafting/navigationupgrade.json b/src/main/resources/data/opencomputers/recipes/recrafting/navigationupgrade.json new file mode 100644 index 0000000000..d7cedbd10e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/recrafting/navigationupgrade.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:navigationupgrade" + }, + { + "item": "minecraft:filled_map" + } + ], + "result": { + "item": "opencomputers:navigationupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/recrafting/robot.json b/src/main/resources/data/opencomputers/recipes/recrafting/robot.json new file mode 100644 index 0000000000..57d4928905 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/recrafting/robot.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:robot" + }, + { + "item": "opencomputers:eeprom" + } + ], + "result": { + "item": "opencomputers:robot" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/recrafting/tablet.json b/src/main/resources/data/opencomputers/recipes/recrafting/tablet.json new file mode 100644 index 0000000000..e871988d2c --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/recrafting/tablet.json @@ -0,0 +1,14 @@ +{ + "type": "opencomputers:crafting_shapeless_extended", + "ingredients": [ + { + "item": "opencomputers:tablet" + }, + { + "item": "opencomputers:eeprom" + } + ], + "result": { + "item": "opencomputers:tablet" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/redstone.json b/src/main/resources/data/opencomputers/recipes/redstone.json new file mode 100644 index 0000000000..9ef9f2986d --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/redstone.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "rRr", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "r": { + "tag": "forge:storage_blocks/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "R": { + "tag": "opencomputers:redstonecard1" + } + }, + "result": { + "item": "opencomputers:redstone" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/redstonecard1.json b/src/main/resources/data/opencomputers/recipes/redstonecard1.json new file mode 100644 index 0000000000..a22d86acd0 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/redstonecard1.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "rC", + " B" + ], + "key": { + "r": { + "item": "minecraft:redstone_torch" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:redstonecard1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/redstonecard2.json b/src/main/resources/data/opencomputers/recipes/redstonecard2.json new file mode 100644 index 0000000000..ac2e427a62 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/redstonecard2.json @@ -0,0 +1,24 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "rCe", + " B " + ], + "key": { + "e": { + "tag": "forge:ender_pearls" + }, + "r": { + "tag": "forge:storage_blocks/redstone" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:redstonecard2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/relay.json b/src/main/resources/data/opencomputers/recipes/relay.json new file mode 100644 index 0000000000..566e5e56e3 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/relay.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ici", + "cLc", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "c": { + "tag": "opencomputers:cable" + }, + "L": { + "tag": "opencomputers:lancard" + } + }, + "result": { + "item": "opencomputers:relay" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/screen1.json b/src/main/resources/data/opencomputers/recipes/screen1.json new file mode 100644 index 0000000000..7157d7ce7e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/screen1.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iri", + "rCG", + "iri" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "G": { + "tag": "forge:glass" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:screen1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/screen2.json b/src/main/resources/data/opencomputers/recipes/screen2.json new file mode 100644 index 0000000000..061b2621b2 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/screen2.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gcg", + "pCG", + "gyg" + ], + "key": { + "c": { + "tag": "forge:dyes/red" + }, + "p": { + "tag": "forge:dyes/green" + }, + "y": { + "tag": "forge:dyes/blue" + }, + "g": { + "tag": "forge:ingots/gold" + }, + "G": { + "tag": "forge:glass" + }, + "C": { + "tag": "opencomputers:circuitchip2" + } + }, + "result": { + "item": "opencomputers:screen2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/screen3.json b/src/main/resources/data/opencomputers/recipes/screen3.json new file mode 100644 index 0000000000..285bc5058a --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/screen3.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ogo", + "gCG", + "ogo" + ], + "key": { + "g": { + "tag": "forge:dusts/glowstone" + }, + "G": { + "tag": "forge:glass" + }, + "o": { + "tag": "forge:obsidian" + }, + "C": { + "tag": "opencomputers:circuitchip3" + } + }, + "result": { + "item": "opencomputers:screen3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/server1.json b/src/main/resources/data/opencomputers/recipes/server1.json new file mode 100644 index 0000000000..cc5f366766 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/server1.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iRi", + "CBC", + "oPo" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "o": { + "tag": "forge:obsidian" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "B": { + "tag": "opencomputers:componentbus1" + }, + "R": { + "tag": "opencomputers:ram2" + } + }, + "result": { + "item": "opencomputers:server1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/server2.json b/src/main/resources/data/opencomputers/recipes/server2.json new file mode 100644 index 0000000000..6e19104647 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/server2.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gRg", + "CBC", + "oPo" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "o": { + "tag": "forge:obsidian" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "B": { + "tag": "opencomputers:componentbus2" + }, + "R": { + "tag": "opencomputers:ram4" + } + }, + "result": { + "item": "opencomputers:server2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/server3.json b/src/main/resources/data/opencomputers/recipes/server3.json new file mode 100644 index 0000000000..3c8651e26e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/server3.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "dRd", + "CBC", + "oPo" + ], + "key": { + "d": { + "tag": "forge:gems/diamond" + }, + "o": { + "tag": "forge:obsidian" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "B": { + "tag": "opencomputers:componentbus3" + }, + "R": { + "tag": "opencomputers:ram6" + } + }, + "result": { + "item": "opencomputers:server3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/signupgrade.json b/src/main/resources/data/opencomputers/recipes/signupgrade.json new file mode 100644 index 0000000000..a9ff81200e --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/signupgrade.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ibi", + "CsC", + "ipi" + ], + "key": { + "s": { + "tag": "forge:rods/wooden" + }, + "b": { + "tag": "forge:dyes/black" + }, + "i": { + "tag": "forge:ingots/iron" + }, + "p": { + "item": "minecraft:sticky_piston" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:signupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/solargeneratorupgrade.json b/src/main/resources/data/opencomputers/recipes/solargeneratorupgrade.json new file mode 100644 index 0000000000..92f5643f16 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/solargeneratorupgrade.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "ggg", + "ClC", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:glass" + }, + "l": { + "tag": "forge:storage_blocks/lapis" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:solargeneratorupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/stickypistonupgrade.json b/src/main/resources/data/opencomputers/recipes/stickypistonupgrade.json new file mode 100644 index 0000000000..0316de4caa --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/stickypistonupgrade.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:crafting_shapeless", + "ingredients": [ + { + "tag": "opencomputers:pistonupgrade" + }, + { + "tag": "forge:slimeballs" + } + ], + "result": { + "item": "opencomputers:stickypistonupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/tabletcase1.json b/src/main/resources/data/opencomputers/recipes/tabletcase1.json new file mode 100644 index 0000000000..df3725413c --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/tabletcase1.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gbg", + "BMC", + "gPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "b": { + "item": "minecraft:stone_button" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "B": { + "tag": "opencomputers:componentbus1" + }, + "M": { + "tag": "opencomputers:screen2" + } + }, + "result": { + "item": "opencomputers:tabletcase1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/tabletcase2.json b/src/main/resources/data/opencomputers/recipes/tabletcase2.json new file mode 100644 index 0000000000..7c8aec84d6 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/tabletcase2.json @@ -0,0 +1,34 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "cbg", + "BMC", + "cPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "b": { + "item": "minecraft:stone_button" + }, + "c": { + "tag": "opencomputers:circuitchip2" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "B": { + "tag": "opencomputers:componentbus3" + }, + "M": { + "tag": "opencomputers:screen2" + } + }, + "result": { + "item": "opencomputers:tabletcase2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/tankcontrollerupgrade.json b/src/main/resources/data/opencomputers/recipes/tankcontrollerupgrade.json new file mode 100644 index 0000000000..959ab130e7 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/tankcontrollerupgrade.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gbg", + "dCp", + "gPg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "b": { + "item": "minecraft:glass_bottle" + }, + "d": { + "item": "minecraft:dispenser" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:tankcontrollerupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/tankupgrade.json b/src/main/resources/data/opencomputers/recipes/tankupgrade.json new file mode 100644 index 0000000000..d3418ba101 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/tankupgrade.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "wbw", + "dcp", + "wCw" + ], + "key": { + "w": { + "tag": "minecraft:planks" + }, + "c": { + "item": "minecraft:cauldron" + }, + "b": { + "item": "minecraft:iron_bars" + }, + "d": { + "item": "minecraft:dispenser" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip1" + } + }, + "result": { + "item": "opencomputers:tankupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/terminal.json b/src/main/resources/data/opencomputers/recipes/terminal.json new file mode 100644 index 0000000000..da5b905cbf --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/terminal.json @@ -0,0 +1,31 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iSi", + "CMR", + "iKi" + ], + "key": { + "i": { + "tag": "forge:nuggets/iron" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "M": { + "tag": "opencomputers:screen2" + }, + "K": { + "tag": "opencomputers:keyboard" + }, + "R": { + "tag": "opencomputers:wlancard2" + }, + "S": { + "tag": "opencomputers:solargeneratorupgrade" + } + }, + "result": { + "item": "opencomputers:terminal" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/terminalserver.json b/src/main/resources/data/opencomputers/recipes/terminalserver.json new file mode 100644 index 0000000000..34c4050148 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/terminalserver.json @@ -0,0 +1,25 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "oRo", + "RCR", + "oPo" + ], + "key": { + "o": { + "tag": "forge:obsidian" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "R": { + "tag": "opencomputers:wlancard2" + } + }, + "result": { + "item": "opencomputers:terminalserver" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/texturepicker.json b/src/main/resources/data/opencomputers/recipes/texturepicker.json new file mode 100644 index 0000000000..c8523a4ba0 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/texturepicker.json @@ -0,0 +1,40 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "DRG", + "BAP", + "YMW" + ], + "key": { + "D": { + "tag": "forge:dyes/black" + }, + "R": { + "tag": "forge:dyes/red" + }, + "G": { + "tag": "forge:dyes/green" + }, + "B": { + "tag": "forge:dyes/blue" + }, + "P": { + "tag": "forge:dyes/purple" + }, + "Y": { + "tag": "forge:dyes/yellow" + }, + "M": { + "tag": "forge:dyes/magenta" + }, + "W": { + "tag": "forge:dyes/white" + }, + "A": { + "tag": "opencomputers:analyzer" + } + }, + "result": { + "item": "opencomputers:texturepicker" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/tractorbeamupgrade.json b/src/main/resources/data/opencomputers/recipes/tractorbeamupgrade.json new file mode 100644 index 0000000000..1d541f8e33 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/tractorbeamupgrade.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gpg", + "iBi", + "gCg" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:ingots/gold" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip3" + }, + "B": { + "tag": "opencomputers:capacitor" + } + }, + "result": { + "item": "opencomputers:tractorbeamupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/tradingupgrade.json b/src/main/resources/data/opencomputers/recipes/tradingupgrade.json new file mode 100644 index 0000000000..741371de22 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/tradingupgrade.json @@ -0,0 +1,34 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gcg", + "eCe", + "dPp" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "e": { + "tag": "forge:gems/emerald" + }, + "c": { + "tag": "forge:chests" + }, + "d": { + "item": "minecraft:dropper" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:tradingupgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/transistor.json b/src/main/resources/data/opencomputers/recipes/transistor.json new file mode 100644 index 0000000000..92ab21d0c6 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/transistor.json @@ -0,0 +1,26 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iii", + "gpg", + " r " + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "g": { + "tag": "forge:nuggets/gold" + }, + "r": { + "tag": "forge:dusts/redstone" + }, + "p": { + "item": "minecraft:paper" + } + }, + "result": { + "item": "opencomputers:transistor", + "count": 8 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/transposer.json b/src/main/resources/data/opencomputers/recipes/transposer.json new file mode 100644 index 0000000000..0bd83c4c43 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/transposer.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iIi", + "hbh", + "iTi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "b": { + "item": "minecraft:bucket" + }, + "h": { + "item": "minecraft:hopper" + }, + "I": { + "tag": "opencomputers:inventorycontrollerupgrade" + }, + "T": { + "tag": "opencomputers:tankcontrollerupgrade" + } + }, + "result": { + "item": "opencomputers:transposer", + "count": 4 + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/upgradecontainer1.json b/src/main/resources/data/opencomputers/recipes/upgradecontainer1.json new file mode 100644 index 0000000000..e6bc47e0f1 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/upgradecontainer1.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "pc ", + "iBi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "c": { + "tag": "forge:chests" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:upgradecontainer1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/upgradecontainer2.json b/src/main/resources/data/opencomputers/recipes/upgradecontainer2.json new file mode 100644 index 0000000000..c097e3fcb5 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/upgradecontainer2.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "pc ", + "iBi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "c": { + "tag": "forge:chests" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:upgradecontainer2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/upgradecontainer3.json b/src/main/resources/data/opencomputers/recipes/upgradecontainer3.json new file mode 100644 index 0000000000..47c980d932 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/upgradecontainer3.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "gCg", + "pc ", + "gBg" + ], + "key": { + "g": { + "tag": "forge:ingots/gold" + }, + "c": { + "tag": "forge:chests" + }, + "p": { + "tag": "forge:pistons" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:materialcircuitboardprinted" + } + }, + "result": { + "item": "opencomputers:upgradecontainer3" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/waypoint.json b/src/main/resources/data/opencomputers/recipes/waypoint.json new file mode 100644 index 0000000000..a8998b1a69 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/waypoint.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "iCi", + "TIT", + "iPi" + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "T": { + "tag": "opencomputers:materialtransistor" + }, + "P": { + "tag": "opencomputers:materialcircuitboardprinted" + }, + "I": { + "tag": "opencomputers:materialinterweb" + } + }, + "result": { + "item": "opencomputers:waypoint" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/wlancard1.json b/src/main/resources/data/opencomputers/recipes/wlancard1.json new file mode 100644 index 0000000000..0d728e324f --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/wlancard1.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "rCr", + " B " + ], + "key": { + "r": { + "item": "minecraft:redstone_torch" + }, + "C": { + "tag": "opencomputers:circuitchip1" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:wlancard1" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/wlancard2.json b/src/main/resources/data/opencomputers/recipes/wlancard2.json new file mode 100644 index 0000000000..42e2c20ed6 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/wlancard2.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "eC", + " B" + ], + "key": { + "e": { + "tag": "forge:ender_pearls" + }, + "C": { + "tag": "opencomputers:circuitchip2" + }, + "B": { + "tag": "opencomputers:materialcard" + } + }, + "result": { + "item": "opencomputers:wlancard2" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/recipes/wrench.json b/src/main/resources/data/opencomputers/recipes/wrench.json new file mode 100644 index 0000000000..1d1ee14115 --- /dev/null +++ b/src/main/resources/data/opencomputers/recipes/wrench.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "i i", + " C ", + " i " + ], + "key": { + "i": { + "tag": "forge:ingots/iron" + }, + "C": { + "tag": "opencomputers:circuitchip2" + } + }, + "result": { + "item": "opencomputers:wrench" + } +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/adapter.json b/src/main/resources/data/opencomputers/tags/blocks/adapter.json new file mode 100644 index 0000000000..40ea055820 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/adapter.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:adapter" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/assembler.json b/src/main/resources/data/opencomputers/tags/blocks/assembler.json new file mode 100644 index 0000000000..ce253c7d63 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/assembler.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:assembler" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/cable.json b/src/main/resources/data/opencomputers/tags/blocks/cable.json new file mode 100644 index 0000000000..ddf88f324c --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/cable.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cable" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/capacitor.json b/src/main/resources/data/opencomputers/tags/blocks/capacitor.json new file mode 100644 index 0000000000..d5c5604646 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/capacitor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:capacitor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/carpetedcapacitor.json b/src/main/resources/data/opencomputers/tags/blocks/carpetedcapacitor.json new file mode 100644 index 0000000000..3b0f159796 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/carpetedcapacitor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:carpetedcapacitor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/case1.json b/src/main/resources/data/opencomputers/tags/blocks/case1.json new file mode 100644 index 0000000000..36fe770a86 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/case1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:case1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/case2.json b/src/main/resources/data/opencomputers/tags/blocks/case2.json new file mode 100644 index 0000000000..731dfce4f6 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/case2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:case2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/case3.json b/src/main/resources/data/opencomputers/tags/blocks/case3.json new file mode 100644 index 0000000000..81cf6d2e6f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/case3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:case3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/chameliumblock.json b/src/main/resources/data/opencomputers/tags/blocks/chameliumblock.json new file mode 100644 index 0000000000..96191a5dfa --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/chameliumblock.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chameliumblock" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/charger.json b/src/main/resources/data/opencomputers/tags/blocks/charger.json new file mode 100644 index 0000000000..1d72aca9d4 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/charger.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:charger" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/disassembler.json b/src/main/resources/data/opencomputers/tags/blocks/disassembler.json new file mode 100644 index 0000000000..b8edc0505a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/disassembler.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:disassembler" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/diskdrive.json b/src/main/resources/data/opencomputers/tags/blocks/diskdrive.json new file mode 100644 index 0000000000..c672b364d5 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/diskdrive.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:diskdrive" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/geolyzer.json b/src/main/resources/data/opencomputers/tags/blocks/geolyzer.json new file mode 100644 index 0000000000..b5dee04f2f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/geolyzer.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:geolyzer" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/hologram1.json b/src/main/resources/data/opencomputers/tags/blocks/hologram1.json new file mode 100644 index 0000000000..f86e9ea22f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/hologram1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hologram1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/hologram2.json b/src/main/resources/data/opencomputers/tags/blocks/hologram2.json new file mode 100644 index 0000000000..8cd7c2c5fa --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/hologram2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hologram2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/keyboard.json b/src/main/resources/data/opencomputers/tags/blocks/keyboard.json new file mode 100644 index 0000000000..46c3a95875 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/keyboard.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:keyboard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/motionsensor.json b/src/main/resources/data/opencomputers/tags/blocks/motionsensor.json new file mode 100644 index 0000000000..5bedd10526 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/motionsensor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:motionsensor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/netsplitter.json b/src/main/resources/data/opencomputers/tags/blocks/netsplitter.json new file mode 100644 index 0000000000..1a34747e99 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/netsplitter.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:netsplitter" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/powerconverter.json b/src/main/resources/data/opencomputers/tags/blocks/powerconverter.json new file mode 100644 index 0000000000..f1c25c0541 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/powerconverter.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:powerconverter" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/powerdistributor.json b/src/main/resources/data/opencomputers/tags/blocks/powerdistributor.json new file mode 100644 index 0000000000..327ec64106 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/powerdistributor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:powerdistributor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/printer.json b/src/main/resources/data/opencomputers/tags/blocks/printer.json new file mode 100644 index 0000000000..e519cbe8b0 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/printer.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:printer" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/rack.json b/src/main/resources/data/opencomputers/tags/blocks/rack.json new file mode 100644 index 0000000000..5c21c51ef2 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/rack.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:rack" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/raid.json b/src/main/resources/data/opencomputers/tags/blocks/raid.json new file mode 100644 index 0000000000..94d790f968 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/raid.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:raid" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/redstone.json b/src/main/resources/data/opencomputers/tags/blocks/redstone.json new file mode 100644 index 0000000000..b02efc6970 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/redstone.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:redstone" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/relay.json b/src/main/resources/data/opencomputers/tags/blocks/relay.json new file mode 100644 index 0000000000..8777de68ce --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/relay.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:relay" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/screen1.json b/src/main/resources/data/opencomputers/tags/blocks/screen1.json new file mode 100644 index 0000000000..3715f2df5a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/screen1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:screen1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/screen2.json b/src/main/resources/data/opencomputers/tags/blocks/screen2.json new file mode 100644 index 0000000000..43611f12cc --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/screen2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:screen2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/screen3.json b/src/main/resources/data/opencomputers/tags/blocks/screen3.json new file mode 100644 index 0000000000..7747d82efb --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/screen3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:screen3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/transposer.json b/src/main/resources/data/opencomputers/tags/blocks/transposer.json new file mode 100644 index 0000000000..b27df92e33 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/transposer.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:transposer" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/blocks/waypoint.json b/src/main/resources/data/opencomputers/tags/blocks/waypoint.json new file mode 100644 index 0000000000..9096c6243d --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/blocks/waypoint.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:waypoint" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/adapter.json b/src/main/resources/data/opencomputers/tags/items/adapter.json new file mode 100644 index 0000000000..40ea055820 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/adapter.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:adapter" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/analyzer.json b/src/main/resources/data/opencomputers/tags/items/analyzer.json new file mode 100644 index 0000000000..af2238c3ec --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/analyzer.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:analyzer" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/angelupgrade.json b/src/main/resources/data/opencomputers/tags/items/angelupgrade.json new file mode 100644 index 0000000000..e8875be1e9 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/angelupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:angelupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/apu1.json b/src/main/resources/data/opencomputers/tags/items/apu1.json new file mode 100644 index 0000000000..f358b9b068 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/apu1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:apu1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/apu2.json b/src/main/resources/data/opencomputers/tags/items/apu2.json new file mode 100644 index 0000000000..5b2bd1e547 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/apu2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:apu2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/assembler.json b/src/main/resources/data/opencomputers/tags/items/assembler.json new file mode 100644 index 0000000000..ce253c7d63 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/assembler.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:assembler" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/batteryupgrade1.json b/src/main/resources/data/opencomputers/tags/items/batteryupgrade1.json new file mode 100644 index 0000000000..dd85c6333f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/batteryupgrade1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:batteryupgrade1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/batteryupgrade2.json b/src/main/resources/data/opencomputers/tags/items/batteryupgrade2.json new file mode 100644 index 0000000000..68f6cf92e7 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/batteryupgrade2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:batteryupgrade2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/batteryupgrade3.json b/src/main/resources/data/opencomputers/tags/items/batteryupgrade3.json new file mode 100644 index 0000000000..3ede5aa156 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/batteryupgrade3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:batteryupgrade3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/cable.json b/src/main/resources/data/opencomputers/tags/items/cable.json new file mode 100644 index 0000000000..ddf88f324c --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/cable.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cable" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/capacitor.json b/src/main/resources/data/opencomputers/tags/items/capacitor.json new file mode 100644 index 0000000000..d5c5604646 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/capacitor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:capacitor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/cardcontainer1.json b/src/main/resources/data/opencomputers/tags/items/cardcontainer1.json new file mode 100644 index 0000000000..66725d2e88 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/cardcontainer1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cardcontainer1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/cardcontainer2.json b/src/main/resources/data/opencomputers/tags/items/cardcontainer2.json new file mode 100644 index 0000000000..ee5802a3fe --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/cardcontainer2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cardcontainer2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/cardcontainer3.json b/src/main/resources/data/opencomputers/tags/items/cardcontainer3.json new file mode 100644 index 0000000000..5448319176 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/cardcontainer3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cardcontainer3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/carpetedcapacitor.json b/src/main/resources/data/opencomputers/tags/items/carpetedcapacitor.json new file mode 100644 index 0000000000..3b0f159796 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/carpetedcapacitor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:carpetedcapacitor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/case1.json b/src/main/resources/data/opencomputers/tags/items/case1.json new file mode 100644 index 0000000000..36fe770a86 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/case1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:case1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/case2.json b/src/main/resources/data/opencomputers/tags/items/case2.json new file mode 100644 index 0000000000..731dfce4f6 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/case2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:case2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/case3.json b/src/main/resources/data/opencomputers/tags/items/case3.json new file mode 100644 index 0000000000..81cf6d2e6f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/case3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:case3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/chamelium.json b/src/main/resources/data/opencomputers/tags/items/chamelium.json new file mode 100644 index 0000000000..c01615e648 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/chamelium.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chamelium" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/chameliumblock.json b/src/main/resources/data/opencomputers/tags/items/chameliumblock.json new file mode 100644 index 0000000000..96191a5dfa --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/chameliumblock.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chameliumblock" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/charger.json b/src/main/resources/data/opencomputers/tags/items/charger.json new file mode 100644 index 0000000000..1d72aca9d4 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/charger.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:charger" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/chipdiamond.json b/src/main/resources/data/opencomputers/tags/items/chipdiamond.json new file mode 100644 index 0000000000..87db4e1169 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/chipdiamond.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chipdiamond" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/chunkloaderupgrade.json b/src/main/resources/data/opencomputers/tags/items/chunkloaderupgrade.json new file mode 100644 index 0000000000..d430fc32dd --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/chunkloaderupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chunkloaderupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/circuitchip1.json b/src/main/resources/data/opencomputers/tags/items/circuitchip1.json new file mode 100644 index 0000000000..9dccfbae3f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/circuitchip1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chip1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/circuitchip2.json b/src/main/resources/data/opencomputers/tags/items/circuitchip2.json new file mode 100644 index 0000000000..c897187abb --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/circuitchip2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chip2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/circuitchip3.json b/src/main/resources/data/opencomputers/tags/items/circuitchip3.json new file mode 100644 index 0000000000..f5ba9efd4a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/circuitchip3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:chip3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/componentbus1.json b/src/main/resources/data/opencomputers/tags/items/componentbus1.json new file mode 100644 index 0000000000..7f2ca6f071 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/componentbus1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:componentbus1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/componentbus2.json b/src/main/resources/data/opencomputers/tags/items/componentbus2.json new file mode 100644 index 0000000000..90a40eafa3 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/componentbus2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:componentbus2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/componentbus3.json b/src/main/resources/data/opencomputers/tags/items/componentbus3.json new file mode 100644 index 0000000000..098b9f43f1 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/componentbus3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:componentbus3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/cpu1.json b/src/main/resources/data/opencomputers/tags/items/cpu1.json new file mode 100644 index 0000000000..a05cbf708f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/cpu1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cpu1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/cpu2.json b/src/main/resources/data/opencomputers/tags/items/cpu2.json new file mode 100644 index 0000000000..3d4e829a36 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/cpu2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cpu2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/cpu3.json b/src/main/resources/data/opencomputers/tags/items/cpu3.json new file mode 100644 index 0000000000..5205e031a2 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/cpu3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cpu3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/craftingupgrade.json b/src/main/resources/data/opencomputers/tags/items/craftingupgrade.json new file mode 100644 index 0000000000..d830ebe4f9 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/craftingupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:craftingupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/databaseupgrade1.json b/src/main/resources/data/opencomputers/tags/items/databaseupgrade1.json new file mode 100644 index 0000000000..be39cac481 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/databaseupgrade1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:databaseupgrade1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/databaseupgrade2.json b/src/main/resources/data/opencomputers/tags/items/databaseupgrade2.json new file mode 100644 index 0000000000..96e6e155bb --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/databaseupgrade2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:databaseupgrade2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/databaseupgrade3.json b/src/main/resources/data/opencomputers/tags/items/databaseupgrade3.json new file mode 100644 index 0000000000..b58c34e9d2 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/databaseupgrade3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:databaseupgrade3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/datacard1.json b/src/main/resources/data/opencomputers/tags/items/datacard1.json new file mode 100644 index 0000000000..8eab0f3c6f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/datacard1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:datacard1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/datacard2.json b/src/main/resources/data/opencomputers/tags/items/datacard2.json new file mode 100644 index 0000000000..d654568b40 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/datacard2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:datacard2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/datacard3.json b/src/main/resources/data/opencomputers/tags/items/datacard3.json new file mode 100644 index 0000000000..7d458b23c6 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/datacard3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:datacard3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/disassembler.json b/src/main/resources/data/opencomputers/tags/items/disassembler.json new file mode 100644 index 0000000000..b8edc0505a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/disassembler.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:disassembler" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/diskdrive.json b/src/main/resources/data/opencomputers/tags/items/diskdrive.json new file mode 100644 index 0000000000..c672b364d5 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/diskdrive.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:diskdrive" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/diskdrivemountable.json b/src/main/resources/data/opencomputers/tags/items/diskdrivemountable.json new file mode 100644 index 0000000000..8fff553ef6 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/diskdrivemountable.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:diskdrivemountable" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/dronecase1.json b/src/main/resources/data/opencomputers/tags/items/dronecase1.json new file mode 100644 index 0000000000..7c190a7b5d --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/dronecase1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:dronecase1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/dronecase2.json b/src/main/resources/data/opencomputers/tags/items/dronecase2.json new file mode 100644 index 0000000000..aa73252c2e --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/dronecase2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:dronecase2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/eeprom.json b/src/main/resources/data/opencomputers/tags/items/eeprom.json new file mode 100644 index 0000000000..047c279d2b --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/eeprom.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:eeprom" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/experienceupgrade.json b/src/main/resources/data/opencomputers/tags/items/experienceupgrade.json new file mode 100644 index 0000000000..5a1b53a755 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/experienceupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:experienceupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/floppy.json b/src/main/resources/data/opencomputers/tags/items/floppy.json new file mode 100644 index 0000000000..b8a10369a6 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/floppy.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:floppy" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/generatorupgrade.json b/src/main/resources/data/opencomputers/tags/items/generatorupgrade.json new file mode 100644 index 0000000000..97bb3d82dd --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/generatorupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:generatorupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/geolyzer.json b/src/main/resources/data/opencomputers/tags/items/geolyzer.json new file mode 100644 index 0000000000..b5dee04f2f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/geolyzer.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:geolyzer" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/graphicscard1.json b/src/main/resources/data/opencomputers/tags/items/graphicscard1.json new file mode 100644 index 0000000000..26d1c3e174 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/graphicscard1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:graphicscard1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/graphicscard2.json b/src/main/resources/data/opencomputers/tags/items/graphicscard2.json new file mode 100644 index 0000000000..b5ea28761a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/graphicscard2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:graphicscard2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/graphicscard3.json b/src/main/resources/data/opencomputers/tags/items/graphicscard3.json new file mode 100644 index 0000000000..30137a5fd7 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/graphicscard3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:graphicscard3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hdd1.json b/src/main/resources/data/opencomputers/tags/items/hdd1.json new file mode 100644 index 0000000000..d1ecab3167 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hdd1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hdd1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hdd2.json b/src/main/resources/data/opencomputers/tags/items/hdd2.json new file mode 100644 index 0000000000..817933c135 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hdd2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hdd2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hdd3.json b/src/main/resources/data/opencomputers/tags/items/hdd3.json new file mode 100644 index 0000000000..5330fcb450 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hdd3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hdd3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hologram1.json b/src/main/resources/data/opencomputers/tags/items/hologram1.json new file mode 100644 index 0000000000..f86e9ea22f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hologram1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hologram1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hologram2.json b/src/main/resources/data/opencomputers/tags/items/hologram2.json new file mode 100644 index 0000000000..8cd7c2c5fa --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hologram2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hologram2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hoverboots.json b/src/main/resources/data/opencomputers/tags/items/hoverboots.json new file mode 100644 index 0000000000..838b71f60c --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hoverboots.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hoverboots" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hoverupgrade1.json b/src/main/resources/data/opencomputers/tags/items/hoverupgrade1.json new file mode 100644 index 0000000000..8473c87e8f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hoverupgrade1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hoverupgrade1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/hoverupgrade2.json b/src/main/resources/data/opencomputers/tags/items/hoverupgrade2.json new file mode 100644 index 0000000000..c801020560 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/hoverupgrade2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:hoverupgrade2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/inkcartridge.json b/src/main/resources/data/opencomputers/tags/items/inkcartridge.json new file mode 100644 index 0000000000..9d3dd3a212 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/inkcartridge.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:inkcartridge" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/inkcartridgeempty.json b/src/main/resources/data/opencomputers/tags/items/inkcartridgeempty.json new file mode 100644 index 0000000000..d67e451ba5 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/inkcartridgeempty.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:inkcartridgeempty" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/internetcard.json b/src/main/resources/data/opencomputers/tags/items/internetcard.json new file mode 100644 index 0000000000..29a889c3f3 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/internetcard.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:internetcard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/inventorycontrollerupgrade.json b/src/main/resources/data/opencomputers/tags/items/inventorycontrollerupgrade.json new file mode 100644 index 0000000000..7f9fd69e43 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/inventorycontrollerupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:inventorycontrollerupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/inventoryupgrade.json b/src/main/resources/data/opencomputers/tags/items/inventoryupgrade.json new file mode 100644 index 0000000000..b9fdb194fb --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/inventoryupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:inventoryupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/keyboard.json b/src/main/resources/data/opencomputers/tags/items/keyboard.json new file mode 100644 index 0000000000..46c3a95875 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/keyboard.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:keyboard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/lancard.json b/src/main/resources/data/opencomputers/tags/items/lancard.json new file mode 100644 index 0000000000..9562ae20d9 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/lancard.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:lancard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/leashupgrade.json b/src/main/resources/data/opencomputers/tags/items/leashupgrade.json new file mode 100644 index 0000000000..a83ef51852 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/leashupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:leashupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/linkedcard.json b/src/main/resources/data/opencomputers/tags/items/linkedcard.json new file mode 100644 index 0000000000..1066cce0d2 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/linkedcard.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:linkedcard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/manual.json b/src/main/resources/data/opencomputers/tags/items/manual.json new file mode 100644 index 0000000000..d9b481c608 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/manual.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:manual" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialacid.json b/src/main/resources/data/opencomputers/tags/items/materialacid.json new file mode 100644 index 0000000000..e8ccf9c9fd --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialacid.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:acid" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialalu.json b/src/main/resources/data/opencomputers/tags/items/materialalu.json new file mode 100644 index 0000000000..5685dd87f8 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialalu.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:alu" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialarrowkey.json b/src/main/resources/data/opencomputers/tags/items/materialarrowkey.json new file mode 100644 index 0000000000..3f5f54fbed --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialarrowkey.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:arrowkeys" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialbuttongroup.json b/src/main/resources/data/opencomputers/tags/items/materialbuttongroup.json new file mode 100644 index 0000000000..e94376c866 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialbuttongroup.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:buttongroup" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialcard.json b/src/main/resources/data/opencomputers/tags/items/materialcard.json new file mode 100644 index 0000000000..d3ebfaeb8a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialcard.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:card" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialcircuitboard.json b/src/main/resources/data/opencomputers/tags/items/materialcircuitboard.json new file mode 100644 index 0000000000..88fb275eaa --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialcircuitboard.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:circuitboard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialcircuitboardprinted.json b/src/main/resources/data/opencomputers/tags/items/materialcircuitboardprinted.json new file mode 100644 index 0000000000..4c9fe89560 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialcircuitboardprinted.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:printedcircuitboard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialcircuitboardraw.json b/src/main/resources/data/opencomputers/tags/items/materialcircuitboardraw.json new file mode 100644 index 0000000000..f14a4adfce --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialcircuitboardraw.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:rawcircuitboard" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialcu.json b/src/main/resources/data/opencomputers/tags/items/materialcu.json new file mode 100644 index 0000000000..91d0fbdca8 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialcu.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cu" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialcuttingwire.json b/src/main/resources/data/opencomputers/tags/items/materialcuttingwire.json new file mode 100644 index 0000000000..4eb1e57db2 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialcuttingwire.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:cuttingwire" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialdisk.json b/src/main/resources/data/opencomputers/tags/items/materialdisk.json new file mode 100644 index 0000000000..3e078d2187 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialdisk.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:disk" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialinterweb.json b/src/main/resources/data/opencomputers/tags/items/materialinterweb.json new file mode 100644 index 0000000000..fc870e7668 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialinterweb.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:interweb" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialnumpad.json b/src/main/resources/data/opencomputers/tags/items/materialnumpad.json new file mode 100644 index 0000000000..086fe84d12 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialnumpad.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:numpad" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/materialtransistor.json b/src/main/resources/data/opencomputers/tags/items/materialtransistor.json new file mode 100644 index 0000000000..7c9a852165 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/materialtransistor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:transistor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/mfu.json b/src/main/resources/data/opencomputers/tags/items/mfu.json new file mode 100644 index 0000000000..b50de136d8 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/mfu.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:mfu" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/microcontrollercase1.json b/src/main/resources/data/opencomputers/tags/items/microcontrollercase1.json new file mode 100644 index 0000000000..43f32db8c9 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/microcontrollercase1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:microcontrollercase1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/microcontrollercase2.json b/src/main/resources/data/opencomputers/tags/items/microcontrollercase2.json new file mode 100644 index 0000000000..b153013c2c --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/microcontrollercase2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:microcontrollercase2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/motionsensor.json b/src/main/resources/data/opencomputers/tags/items/motionsensor.json new file mode 100644 index 0000000000..5bedd10526 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/motionsensor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:motionsensor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/nanomachines.json b/src/main/resources/data/opencomputers/tags/items/nanomachines.json new file mode 100644 index 0000000000..a332667aa0 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/nanomachines.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:nanomachines" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/navigationupgrade.json b/src/main/resources/data/opencomputers/tags/items/navigationupgrade.json new file mode 100644 index 0000000000..7ac0d12787 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/navigationupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:navigationupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/netsplitter.json b/src/main/resources/data/opencomputers/tags/items/netsplitter.json new file mode 100644 index 0000000000..1a34747e99 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/netsplitter.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:netsplitter" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/pistonupgrade.json b/src/main/resources/data/opencomputers/tags/items/pistonupgrade.json new file mode 100644 index 0000000000..20eda93a1c --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/pistonupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:pistonupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/powerconverter.json b/src/main/resources/data/opencomputers/tags/items/powerconverter.json new file mode 100644 index 0000000000..f1c25c0541 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/powerconverter.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:powerconverter" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/powerdistributor.json b/src/main/resources/data/opencomputers/tags/items/powerdistributor.json new file mode 100644 index 0000000000..327ec64106 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/powerdistributor.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:powerdistributor" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/printer.json b/src/main/resources/data/opencomputers/tags/items/printer.json new file mode 100644 index 0000000000..e519cbe8b0 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/printer.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:printer" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/rack.json b/src/main/resources/data/opencomputers/tags/items/rack.json new file mode 100644 index 0000000000..5c21c51ef2 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/rack.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:rack" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/raid.json b/src/main/resources/data/opencomputers/tags/items/raid.json new file mode 100644 index 0000000000..94d790f968 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/raid.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:raid" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/ram1.json b/src/main/resources/data/opencomputers/tags/items/ram1.json new file mode 100644 index 0000000000..a4dcf07983 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/ram1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:ram1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/ram2.json b/src/main/resources/data/opencomputers/tags/items/ram2.json new file mode 100644 index 0000000000..6c87031c7b --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/ram2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:ram2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/ram3.json b/src/main/resources/data/opencomputers/tags/items/ram3.json new file mode 100644 index 0000000000..7f610e2893 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/ram3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:ram3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/ram4.json b/src/main/resources/data/opencomputers/tags/items/ram4.json new file mode 100644 index 0000000000..a51a2f174a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/ram4.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:ram4" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/ram5.json b/src/main/resources/data/opencomputers/tags/items/ram5.json new file mode 100644 index 0000000000..f9db65e3d0 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/ram5.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:ram5" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/ram6.json b/src/main/resources/data/opencomputers/tags/items/ram6.json new file mode 100644 index 0000000000..fdc3a46ab4 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/ram6.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:ram6" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/redstone.json b/src/main/resources/data/opencomputers/tags/items/redstone.json new file mode 100644 index 0000000000..b02efc6970 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/redstone.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:redstone" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/redstonecard1.json b/src/main/resources/data/opencomputers/tags/items/redstonecard1.json new file mode 100644 index 0000000000..f3b377bdcf --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/redstonecard1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:redstonecard1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/redstonecard2.json b/src/main/resources/data/opencomputers/tags/items/redstonecard2.json new file mode 100644 index 0000000000..99f07d8657 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/redstonecard2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:redstonecard2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/relay.json b/src/main/resources/data/opencomputers/tags/items/relay.json new file mode 100644 index 0000000000..8777de68ce --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/relay.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:relay" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/screen1.json b/src/main/resources/data/opencomputers/tags/items/screen1.json new file mode 100644 index 0000000000..3715f2df5a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/screen1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:screen1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/screen2.json b/src/main/resources/data/opencomputers/tags/items/screen2.json new file mode 100644 index 0000000000..43611f12cc --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/screen2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:screen2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/screen3.json b/src/main/resources/data/opencomputers/tags/items/screen3.json new file mode 100644 index 0000000000..7747d82efb --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/screen3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:screen3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/server1.json b/src/main/resources/data/opencomputers/tags/items/server1.json new file mode 100644 index 0000000000..4d02054e2f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/server1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:server1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/server2.json b/src/main/resources/data/opencomputers/tags/items/server2.json new file mode 100644 index 0000000000..bec50adc68 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/server2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:server2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/server3.json b/src/main/resources/data/opencomputers/tags/items/server3.json new file mode 100644 index 0000000000..513579991a --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/server3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:server3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/signupgrade.json b/src/main/resources/data/opencomputers/tags/items/signupgrade.json new file mode 100644 index 0000000000..a23e2aa3dd --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/signupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:signupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/solargeneratorupgrade.json b/src/main/resources/data/opencomputers/tags/items/solargeneratorupgrade.json new file mode 100644 index 0000000000..10b9e99dca --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/solargeneratorupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:solargeneratorupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/stickypistonupgrade.json b/src/main/resources/data/opencomputers/tags/items/stickypistonupgrade.json new file mode 100644 index 0000000000..4c5f04cff8 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/stickypistonupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:stickypistonupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/tabletcase1.json b/src/main/resources/data/opencomputers/tags/items/tabletcase1.json new file mode 100644 index 0000000000..5e42ce3d02 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/tabletcase1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:tabletcase1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/tabletcase2.json b/src/main/resources/data/opencomputers/tags/items/tabletcase2.json new file mode 100644 index 0000000000..d971384a20 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/tabletcase2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:tabletcase2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/tankcontrollerupgrade.json b/src/main/resources/data/opencomputers/tags/items/tankcontrollerupgrade.json new file mode 100644 index 0000000000..31fd709c36 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/tankcontrollerupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:tankcontrollerupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/tankupgrade.json b/src/main/resources/data/opencomputers/tags/items/tankupgrade.json new file mode 100644 index 0000000000..29f0047b03 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/tankupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:tankupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/terminal.json b/src/main/resources/data/opencomputers/tags/items/terminal.json new file mode 100644 index 0000000000..aa9109ac64 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/terminal.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:terminal" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/terminalserver.json b/src/main/resources/data/opencomputers/tags/items/terminalserver.json new file mode 100644 index 0000000000..ce1e0bd0cf --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/terminalserver.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:terminalserver" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/texturepicker.json b/src/main/resources/data/opencomputers/tags/items/texturepicker.json new file mode 100644 index 0000000000..12d8e59604 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/texturepicker.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:texturepicker" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/tractorbeamupgrade.json b/src/main/resources/data/opencomputers/tags/items/tractorbeamupgrade.json new file mode 100644 index 0000000000..2d1d93a476 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/tractorbeamupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:tractorbeamupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/tradingupgrade.json b/src/main/resources/data/opencomputers/tags/items/tradingupgrade.json new file mode 100644 index 0000000000..5fc253cc65 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/tradingupgrade.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:tradingupgrade" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/transposer.json b/src/main/resources/data/opencomputers/tags/items/transposer.json new file mode 100644 index 0000000000..b27df92e33 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/transposer.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:transposer" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/upgradecontainer1.json b/src/main/resources/data/opencomputers/tags/items/upgradecontainer1.json new file mode 100644 index 0000000000..d4d4f8100c --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/upgradecontainer1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:upgradecontainer1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/upgradecontainer2.json b/src/main/resources/data/opencomputers/tags/items/upgradecontainer2.json new file mode 100644 index 0000000000..ed7a840a9e --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/upgradecontainer2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:upgradecontainer2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/upgradecontainer3.json b/src/main/resources/data/opencomputers/tags/items/upgradecontainer3.json new file mode 100644 index 0000000000..50a255cca5 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/upgradecontainer3.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:upgradecontainer3" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/waypoint.json b/src/main/resources/data/opencomputers/tags/items/waypoint.json new file mode 100644 index 0000000000..9096c6243d --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/waypoint.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:waypoint" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/wlancard1.json b/src/main/resources/data/opencomputers/tags/items/wlancard1.json new file mode 100644 index 0000000000..50b4f85d5f --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/wlancard1.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:wlancard1" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/wlancard2.json b/src/main/resources/data/opencomputers/tags/items/wlancard2.json new file mode 100644 index 0000000000..df25029370 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/wlancard2.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:wlancard2" + ] +} \ No newline at end of file diff --git a/src/main/resources/data/opencomputers/tags/items/wrench.json b/src/main/resources/data/opencomputers/tags/items/wrench.json new file mode 100644 index 0000000000..af355bef28 --- /dev/null +++ b/src/main/resources/data/opencomputers/tags/items/wrench.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "opencomputers:wrench" + ] +} \ No newline at end of file diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info deleted file mode 100644 index 15b6e128f8..0000000000 --- a/src/main/resources/mcmod.info +++ /dev/null @@ -1,17 +0,0 @@ -[{ - "modid": "opencomputers", - "name": "OpenComputers", - "description": "This mod adds modular computers and robots that can be programmed in Lua.", - "version": "${version}", - "mcversion": "${mcversion}", - "url": "http://oc.cil.li/", - "authorList": ["Sangar", "Vexatos", "payonel", "magik6k", "Lord Joda", "Github Contributors"], - "credits" : "Inspired by a couple of other mods, most notably ComputerCraft.", - "logoFile" : "assets/opencomputers/textures/gui/logo.png", - "requiredMods": [], - "dependencies": [ - "JEI@[4.2.7.240,)" - ], - "dependants": [], - "useDependencyInformation": "true" -}] diff --git a/src/main/resources/oc_at.cfg b/src/main/resources/oc_at.cfg deleted file mode 100644 index 1c841fa0fb..0000000000 --- a/src/main/resources/oc_at.cfg +++ /dev/null @@ -1,11 +0,0 @@ - # OpenComputers access transformer config -public net.minecraft.client.gui.inventory.GuiContainer field_146999_f #xSize -public net.minecraft.client.gui.inventory.GuiContainer field_147000_g #ySize -public net.minecraft.client.gui.inventory.GuiContainer field_147003_i #guiLeft -public net.minecraft.client.gui.inventory.GuiContainer field_147009_r #guiTop -public net.minecraft.block.BlockPistonBase func_176319_a(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;Z)Z # doMove -public net.minecraft.client.audio.SoundManager field_148620_e #sndSystem -public net.minecraft.client.audio.SoundManager$SoundSystemStarterThread -#public net.minecraft.enchantment.Enchantment field_180311_a # enchantmentsList -public net.minecraft.tileentity.MobSpawnerBaseLogic func_190895_g()Lnet/minecraft/util/ResourceLocation; # getEntityId -public net.minecraft.entity.Entity func_180432_n(Lnet/minecraft/entity/Entity;)V # copyDataFromOld diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 0000000000..4a3edd6ccb --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "OpenComputers resources", + "pack_format": 6 + } +} diff --git a/src/main/resources/pack.png b/src/main/resources/pack.png new file mode 100644 index 0000000000..65bb8c54e4 Binary files /dev/null and b/src/main/resources/pack.png differ diff --git a/src/main/scala/li/cil/oc/CreativeTab.scala b/src/main/scala/li/cil/oc/CreativeTab.scala index 1a54db307c..5ed9ef4431 100644 --- a/src/main/scala/li/cil/oc/CreativeTab.scala +++ b/src/main/scala/li/cil/oc/CreativeTab.scala @@ -1,11 +1,17 @@ package li.cil.oc -import net.minecraft.creativetab.CreativeTabs +import li.cil.oc.common.init.Items +import net.minecraft.item.ItemGroup +import net.minecraft.item.ItemStack +import net.minecraft.util.NonNullList -object CreativeTab extends CreativeTabs(CreativeTabs.getNextID, OpenComputers.Name) { +object CreativeTab extends ItemGroup(OpenComputers.Name) { private lazy val stack = api.Items.get(Constants.BlockName.CaseTier1).createItemStack(1) - override def getTabIconItem = stack + override def makeIcon = stack - override def getTranslatedTabLabel = getTabLabel + override def fillItemList(list: NonNullList[ItemStack]) { + super.fillItemList(list) + Items.decorateCreativeTab(list) + } } diff --git a/src/main/scala/li/cil/oc/Localization.scala b/src/main/scala/li/cil/oc/Localization.scala index d66c0be78a..6d83b8977c 100644 --- a/src/main/scala/li/cil/oc/Localization.scala +++ b/src/main/scala/li/cil/oc/Localization.scala @@ -1,62 +1,65 @@ package li.cil.oc -import li.cil.oc.client.CommandHandler.SetClipboardCommand -import net.minecraft.util.text.ITextComponent -import net.minecraft.util.text.TextComponentString -import net.minecraft.util.text.TextComponentTranslation +import net.minecraft.util.text._ import net.minecraft.util.text.event.ClickEvent import net.minecraft.util.text.event.HoverEvent -import net.minecraft.util.text.translation.I18n -import net.minecraftforge.fml.common.event.FMLFingerprintViolationEvent import scala.util.matching.Regex object Localization { - private val nl = Regex.quote("[nl]") - private def resolveKey(key: String) = if (canLocalize(Settings.namespace + key)) Settings.namespace + key else key - def canLocalize(key: String): Boolean = I18n.canTranslate(key) + def canLocalize(key: String): Boolean = LanguageMap.getInstance.has(key) - def localizeLater(formatKey: String, values: AnyRef*) = new TextComponentTranslation(resolveKey(formatKey), values: _*) + def localizeLater(formatKey: String, values: AnyRef*) = new TranslationTextComponent(resolveKey(formatKey), values: _*) - def localizeLater(key: String) = new TextComponentTranslation(resolveKey(key)) + def localizeLater(key: String) = new TranslationTextComponent(resolveKey(key)) - def localizeImmediately(formatKey: String, values: AnyRef*): String = I18n.translateToLocalFormatted(resolveKey(formatKey), values: _*).split(nl).map(_.trim).mkString("\n") + def localizeImmediately(formatKey: String, values: AnyRef*): String = { + val k = resolveKey(formatKey) + var lm = LanguageMap.getInstance + if (!lm.has(k)) return k + String.format(lm.getOrDefault(k), values: _*).lines.map(_.trim).mkString("\n") + } - def localizeImmediately(key: String): String = I18n.translateToLocal(resolveKey(key)).split(nl).map(_.trim).mkString("\n") + def localizeImmediately(key: String): String = { + val k = resolveKey(key) + var lm = LanguageMap.getInstance + if (!lm.has(k)) return k + lm.getOrDefault(k).lines.map(_.trim).mkString("\n") + } object Analyzer { - def Address(value: String): TextComponentTranslation = { + def Address(value: String): IFormattableTextComponent = { val result = localizeLater("gui.Analyzer.Address", value) - result.getStyle.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, s"/${SetClipboardCommand.name} $value")) - result.getStyle.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, localizeLater("gui.Analyzer.CopyToClipboard"))) - result + result.setStyle(result.getStyle + .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, value)) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, localizeLater("gui.Analyzer.CopyToClipboard")))) } - def AddressCopied: TextComponentTranslation = localizeLater("gui.Analyzer.AddressCopied") + def AddressCopied: TranslationTextComponent = localizeLater("gui.Analyzer.AddressCopied") - def ChargerSpeed(value: Double): TextComponentTranslation = localizeLater("gui.Analyzer.ChargerSpeed", (value * 100).toInt + "%") + def ChargerSpeed(value: Double): TranslationTextComponent = localizeLater("gui.Analyzer.ChargerSpeed", (value * 100).toInt + "%") - def ComponentName(value: String): TextComponentTranslation = localizeLater("gui.Analyzer.ComponentName", value) + def ComponentName(value: String): TranslationTextComponent = localizeLater("gui.Analyzer.ComponentName", value) - def Components(count: Int, maxCount: Int): TextComponentTranslation = localizeLater("gui.Analyzer.Components", count + "/" + maxCount) + def Components(count: Int, maxCount: Int): TranslationTextComponent = localizeLater("gui.Analyzer.Components", count + "/" + maxCount) - def LastError(value: String): TextComponentTranslation = localizeLater("gui.Analyzer.LastError", localizeLater(value)) + def LastError(value: String): TranslationTextComponent = localizeLater("gui.Analyzer.LastError", localizeLater(value)) - def RobotOwner(owner: String): TextComponentTranslation = localizeLater("gui.Analyzer.RobotOwner", owner) + def RobotOwner(owner: String): TranslationTextComponent = localizeLater("gui.Analyzer.RobotOwner", owner) - def RobotName(name: String): TextComponentTranslation = localizeLater("gui.Analyzer.RobotName", name) + def RobotName(name: String): TranslationTextComponent = localizeLater("gui.Analyzer.RobotName", name) - def RobotXp(experience: Double, level: Int): TextComponentTranslation = localizeLater("gui.Analyzer.RobotXp", f"$experience%.2f", level.toString) + def RobotXp(experience: Double, level: Int): TranslationTextComponent = localizeLater("gui.Analyzer.RobotXp", f"$experience%.2f", level.toString) - def StoredEnergy(value: String): TextComponentTranslation = localizeLater("gui.Analyzer.StoredEnergy", value) + def StoredEnergy(value: String): TranslationTextComponent = localizeLater("gui.Analyzer.StoredEnergy", value) - def TotalEnergy(value: String): TextComponentTranslation = localizeLater("gui.Analyzer.TotalEnergy", value) + def TotalEnergy(value: String): TranslationTextComponent = localizeLater("gui.Analyzer.TotalEnergy", value) - def Users(list: Iterable[String]): TextComponentTranslation = localizeLater("gui.Analyzer.Users", list.mkString(", ")) + def Users(list: Iterable[String]): TranslationTextComponent = localizeLater("gui.Analyzer.Users", list.mkString(", ")) - def WirelessStrength(value: Double): TextComponentTranslation = localizeLater("gui.Analyzer.WirelessStrength", value.toInt.toString) + def WirelessStrength(value: Double): TranslationTextComponent = localizeLater("gui.Analyzer.WirelessStrength", value.toInt.toString) } object Assembler { @@ -64,13 +67,13 @@ object Localization { def CollectResult: String = localizeImmediately("gui.Assembler.Collect") - def InsertCPU: TextComponentTranslation = localizeLater("gui.Assembler.InsertCPU") + def InsertCPU: TranslationTextComponent = localizeLater("gui.Assembler.InsertCPU") - def InsertRAM: TextComponentTranslation = localizeLater("gui.Assembler.InsertRAM") + def InsertRAM: TranslationTextComponent = localizeLater("gui.Assembler.InsertRAM") def Complexity(complexity: Int, maxComplexity: Int): ITextComponent = { val message = localizeLater("gui.Assembler.Complexity", complexity.toString, maxComplexity.toString) - if (complexity > maxComplexity) new TextComponentString("§4").appendSibling(message) + if (complexity > maxComplexity) new StringTextComponent("§4").append(message) else message } @@ -78,29 +81,25 @@ object Localization { def Progress(progress: Double, timeRemaining: String): String = localizeImmediately("gui.Assembler.Progress", progress.toInt.toString, timeRemaining) - def Warning(name: String): ITextComponent = new TextComponentString("§7- ").appendSibling(localizeLater("gui.Assembler.Warning." + name)) + def Warning(name: String): ITextComponent = new StringTextComponent("§7- ").append(localizeLater("gui.Assembler.Warning." + name)) - def Warnings: TextComponentTranslation = localizeLater("gui.Assembler.Warnings") + def Warnings: TranslationTextComponent = localizeLater("gui.Assembler.Warnings") } object Chat { - def WarningLuaFallback: ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningLuaFallback")) - - def WarningProjectRed: ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningProjectRed")) - - def WarningFingerprint(event: FMLFingerprintViolationEvent): ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningFingerprint", event.getExpectedFingerprint, event.getFingerprints.toArray.mkString(", "))) + def WarningLuaFallback: ITextComponent = new StringTextComponent("§aOpenComputers§f: ").append(localizeLater("gui.Chat.WarningLuaFallback")) - def WarningRecipes: ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningRecipes")) + def WarningProjectRed: ITextComponent = new StringTextComponent("§aOpenComputers§f: ").append(localizeLater("gui.Chat.WarningProjectRed")) - def WarningClassTransformer: ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningClassTransformer")) + def WarningRecipes: ITextComponent = new StringTextComponent("§aOpenComputers§f: ").append(localizeLater("gui.Chat.WarningRecipes")) - def WarningSimpleComponent: ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningSimpleComponent")) + def WarningClassTransformer: ITextComponent = new StringTextComponent("§aOpenComputers§f: ").append(localizeLater("gui.Chat.WarningClassTransformer")) - def WarningLink(url: String): ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.WarningLink", url)) + def WarningLink(url: String): ITextComponent = new StringTextComponent("§aOpenComputers§f: ").append(localizeLater("gui.Chat.WarningLink", url)) - def InfoNewVersion(version: String): ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.NewVersion", version)) + def InfoNewVersion(version: String): ITextComponent = new StringTextComponent("§aOpenComputers§f: ").append(localizeLater("gui.Chat.NewVersion", version)) - def TextureName(name: String): ITextComponent = new TextComponentString("§aOpenComputers§f: ").appendSibling(localizeLater("gui.Chat.TextureName", name)) + def TextureName(name: String): ITextComponent = new StringTextComponent("§aOpenComputers§f: ").append(localizeLater("gui.Chat.TextureName", name)) } object Computer { @@ -156,9 +155,9 @@ object Localization { } object Terminal { - def InvalidKey: TextComponentTranslation = localizeLater("gui.Terminal.InvalidKey") + def InvalidKey: TranslationTextComponent = localizeLater("gui.Terminal.InvalidKey") - def OutOfRange: TextComponentTranslation = localizeLater("gui.Terminal.OutOfRange") + def OutOfRange: TranslationTextComponent = localizeLater("gui.Terminal.OutOfRange") } object Tooltip { diff --git a/src/main/scala/li/cil/oc/OpenComputers.scala b/src/main/scala/li/cil/oc/OpenComputers.scala index 668d1cf536..b6895b6c78 100644 --- a/src/main/scala/li/cil/oc/OpenComputers.scala +++ b/src/main/scala/li/cil/oc/OpenComputers.scala @@ -1,67 +1,89 @@ package li.cil.oc +import java.nio.file.Paths + import li.cil.oc.common.IMC import li.cil.oc.common.Proxy -import li.cil.oc.server.command.CommandHandler -import net.minecraftforge.fml.common.Mod -import net.minecraftforge.fml.common.Mod.EventHandler -import net.minecraftforge.fml.common.SidedProxy -import net.minecraftforge.fml.common.event.FMLInterModComms.IMCEvent -import net.minecraftforge.fml.common.event._ -import net.minecraftforge.fml.common.network.FMLEventChannel +import li.cil.oc.common.init.Blocks +import li.cil.oc.common.init.Items +import li.cil.oc.integration.Mods import li.cil.oc.util.ThreadPoolFactory +import net.minecraft.block.Block +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.world.World +import net.minecraftforge.event.RegistryEvent +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.forgespi.Environment +import net.minecraftforge.fml.InterModComms +import net.minecraftforge.fml.ModContainer +import net.minecraftforge.fml.ModLoadingContext +import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent +import net.minecraftforge.fml.loading.FMLPaths +import net.minecraftforge.fml.network.simple.SimpleChannel +import net.minecraftforge.scorge.lang.ScorgeModLoadingContext import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger -@Mod(modid = OpenComputers.ID, name = OpenComputers.Name, - version = OpenComputers.Version, - modLanguage = "scala", useMetadata = true /*@MCVERSIONDEP@*/) +import scala.collection.convert.ImplicitConversionsToScala._ + object OpenComputers { final val ID = "opencomputers" final val Name = "OpenComputers" - final val Version = "@VERSION@" - - def log: Logger = logger.getOrElse(LogManager.getLogger(Name)) + final val log: Logger = LogManager.getLogger(Name) - var logger: Option[Logger] = None + lazy val proxy: Proxy = { + val cls = Environment.get.getDist match { + case Dist.CLIENT => Class.forName("li.cil.oc.client.Proxy") + case _ => Class.forName("li.cil.oc.common.Proxy") + } + cls.getConstructor().newInstance().asInstanceOf[Proxy] + } - @SidedProxy(clientSide = "li.cil.oc.client.Proxy", serverSide = "li.cil.oc.server.Proxy") - var proxy: Proxy = null + var channel: SimpleChannel = null - var channel: FMLEventChannel = _ + private var instance: Option[OpenComputers] = None - @EventHandler - def preInit(e: FMLPreInitializationEvent) { - logger = Option(e.getModLog) - proxy.preInit(e) - OpenComputers.log.info("Done with pre init phase.") + def get = instance match { + case Some(oc) => oc + case _ => throw new IllegalStateException("not initialized") } +} - @EventHandler - def init(e: FMLInitializationEvent): Unit = { - proxy.init(e) - OpenComputers.log.info("Done with init phase.") - } +class OpenComputers { + val modContainer: ModContainer = ModLoadingContext.get.getActiveContainer - @EventHandler - def postInit(e: FMLPostInitializationEvent): Unit = { - proxy.postInit(e) - OpenComputers.log.info("Done with post init phase.") - } + val Version = modContainer.getModInfo.getVersion + + ScorgeModLoadingContext.get.getModEventBus.register(this) + OpenComputers.instance = Some(this) - @EventHandler - def serverStart(e: FMLServerStartingEvent): Unit = { - CommandHandler.register(e) - ThreadPoolFactory.safePools.foreach(_.newThreadPool()) + MinecraftForge.EVENT_BUS.register(OpenComputers.proxy) + ScorgeModLoadingContext.get.getModEventBus.register(OpenComputers.proxy) + Settings.load(FMLPaths.CONFIGDIR.get().resolve(Paths.get("opencomputers", "settings.conf")).toFile()) + OpenComputers.proxy.preInit() + MinecraftForge.EVENT_BUS.register(ThreadPoolFactory) + Mods.preInit() // Must happen after loading Settings but before registry events are fired. + + @SubscribeEvent + def registerBlocks(e: RegistryEvent.Register[Block]) { + Blocks.init() } - @EventHandler - def serverStop(e: FMLServerStoppedEvent): Unit = { - ThreadPoolFactory.safePools.foreach(_.waitForCompletion()) + @SubscribeEvent + def registerItems(e: RegistryEvent.Register[Item]) { + Items.init() } - @EventHandler - def imc(e: IMCEvent): Unit = IMC.handleEvent(e) + @SubscribeEvent + def imc(e: InterModProcessEvent): Unit = { + // Technically requires synchronization because IMC.sendTo doesn't check the loading stage. + e.enqueueWork((() => { + InterModComms.getMessages(OpenComputers.ID).sequential.iterator.foreach(IMC.handleMessage) + }): Runnable) + } } diff --git a/src/main/scala/li/cil/oc/Settings.scala b/src/main/scala/li/cil/oc/Settings.scala index d632a68283..93d043869b 100644 --- a/src/main/scala/li/cil/oc/Settings.scala +++ b/src/main/scala/li/cil/oc/Settings.scala @@ -4,6 +4,7 @@ import java.io._ import java.net.Inet4Address import java.net.InetAddress import java.nio.charset.StandardCharsets +import java.nio.file.Paths import java.security.SecureRandom import java.util.UUID @@ -14,16 +15,15 @@ import li.cil.oc.Settings.DebugCardAccess import li.cil.oc.common.Tier import li.cil.oc.server.component.DebugCard import li.cil.oc.server.component.DebugCard.AccessContext +import net.minecraftforge.fml.loading.FMLPaths import org.apache.commons.codec.binary.Hex -import net.minecraftforge.fml.common.Loader -import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion -import net.minecraftforge.fml.common.versioning.VersionRange -import org.apache.commons.lang3.StringEscapeUtils +import org.apache.maven.artifact.versioning.DefaultArtifactVersion +import org.apache.maven.artifact.versioning.VersionRange -import scala.collection.convert.WrapAsScala._ import scala.collection.mutable import scala.io.Codec import scala.io.Source +import scala.jdk.CollectionConverters._ import scala.util.matching.Regex class Settings(val config: Config) { @@ -44,7 +44,7 @@ class Settings(val config: Config) { val beepSampleRate = config.getInt("client.beepSampleRate") val beepAmplitude = config.getInt("client.beepVolume") max 0 min Byte.MaxValue val beepRadius = config.getDouble("client.beepRadius").toFloat max 1 min 32 - val nanomachineHudPos = Array(config.getDoubleList("client.nanomachineHudPos"): _*) match { + val nanomachineHudPos = config.getDoubleList("client.nanomachineHudPos").asScala.toArray match { case Array(x, y) => (x: Double, y: Double) case _ => @@ -60,14 +60,14 @@ class Settings(val config: Config) { val startupDelay = config.getDouble("computer.startupDelay") max 0.05 val eepromSize = config.getInt("computer.eepromSize") max 0 val eepromDataSize = config.getInt("computer.eepromDataSize") max 0 - val cpuComponentSupport = Array(config.getIntList("computer.cpuComponentCount"): _*) match { + val cpuComponentSupport = config.getIntList("computer.cpuComponentCount").asScala.toArray match { case Array(tier1, tier2, tier3, tierCreative) => Array(tier1: Int, tier2: Int, tier3: Int, tierCreative: Int) case _ => OpenComputers.log.warn("Bad number of CPU component counts, ignoring.") Array(8, 12, 16, 1024) } - val callBudgets = Array(config.getDoubleList("computer.callBudgets"): _*) match { + val callBudgets = config.getDoubleList("computer.callBudgets").asScala.toArray match { case Array(tier1, tier2, tier3) => Array(tier1: Double, tier2: Double, tier3: Double) case _ => @@ -85,7 +85,7 @@ class Settings(val config: Config) { val allowGC = config.getBoolean("computer.lua.allowGC") val enableLua53 = config.getBoolean("computer.lua.enableLua53") val defaultLua53 = config.getBoolean("computer.lua.defaultLua53") - val ramSizes = Array(config.getIntList("computer.lua.ramSizes"): _*) match { + val ramSizes = config.getIntList("computer.lua.ramSizes").asScala.toArray match { case Array(tier1, tier2, tier3, tier4, tier5, tier6) => Array(tier1: Int, tier2: Int, tier3: Int, tier4: Int, tier5: Int, tier6: Int) case _ => @@ -107,7 +107,7 @@ class Settings(val config: Config) { val itemDamageRate = config.getDouble("robot.itemDamageRate") max 0 min 1 val nameFormat = config.getString("robot.nameFormat") val uuidFormat = config.getString("robot.uuidFormat") - val upgradeFlightHeight = Array(config.getIntList("robot.upgradeFlightHeight"): _*) match { + val upgradeFlightHeight = config.getIntList("robot.upgradeFlightHeight").asScala.toArray match { case Array(tier1, tier2) => Array(tier1: Int, tier2: Int) case _ => @@ -165,7 +165,7 @@ class Settings(val config: Config) { val bufferRobot = config.getDouble("power.buffer.robot") max 0 val bufferConverter = config.getDouble("power.buffer.converter") max 0 val bufferDistributor = config.getDouble("power.buffer.distributor") max 0 - val bufferCapacitorUpgrades = Array(config.getDoubleList("power.buffer.batteryUpgrades"): _*) match { + val bufferCapacitorUpgrades = config.getDoubleList("power.buffer.batteryUpgrades").asScala.toArray match { case Array(tier1, tier2, tier3) => Array(tier1: Double, tier2: Double, tier3: Double) case _ => @@ -196,7 +196,7 @@ class Settings(val config: Config) { val robotTurnCost = config.getDouble("power.cost.robotTurn") max 0 val robotMoveCost = config.getDouble("power.cost.robotMove") max 0 val robotExhaustionCost = config.getDouble("power.cost.robotExhaustion") max 0 - val wirelessCostPerRange = Array(config.getDoubleList("power.cost.wirelessCostPerRange"): _*) match { + val wirelessCostPerRange = config.getDoubleList("power.cost.wirelessCostPerRange").asScala.toArray match { case Array(tier1, tier2) => Array((tier1: Double) max 0.0, (tier2: Double) max 0.0) case _ => @@ -236,7 +236,7 @@ class Settings(val config: Config) { // power.rate val accessPointRate = config.getDouble("power.rate.accessPoint") max 0 val assemblerRate = config.getDouble("power.rate.assembler") max 0 - val caseRate = (Array(config.getDoubleList("power.rate.case"): _*) match { + val caseRate = (config.getDoubleList("power.rate.case").asScala.toArray match { case Array(tier1, tier2, tier3) => Array(tier1: Double, tier2: Double, tier3: Double) case _ => @@ -276,14 +276,14 @@ class Settings(val config: Config) { // filesystem val fileCost = config.getInt("filesystem.fileCost") max 0 val bufferChanges = config.getBoolean("filesystem.bufferChanges") - val hddSizes = Array(config.getIntList("filesystem.hddSizes"): _*) match { + val hddSizes = config.getIntList("filesystem.hddSizes").asScala.toArray match { case Array(tier1, tier2, tier3) => Array(tier1: Int, tier2: Int, tier3: Int) case _ => OpenComputers.log.warn("Bad number of HDD sizes, ignoring.") Array(1024, 2048, 4096) } - val hddPlatterCounts = Array(config.getIntList("filesystem.hddPlatterCounts"): _*) match { + val hddPlatterCounts = config.getIntList("filesystem.hddPlatterCounts").asScala.toArray match { case Array(tier1, tier2, tier3) => Array(tier1: Int, tier2: Int, tier3: Int) case _ => @@ -302,8 +302,8 @@ class Settings(val config: Config) { val httpEnabled = config.getBoolean("internet.enableHttp") val httpHeadersEnabled = config.getBoolean("internet.enableHttpHeaders") val tcpEnabled = config.getBoolean("internet.enableTcp") - val httpHostBlacklist = Array(config.getStringList("internet.blacklist").map(new Settings.AddressValidator(_)): _*) - val httpHostWhitelist = Array(config.getStringList("internet.whitelist").map(new Settings.AddressValidator(_)): _*) + val httpHostBlacklist = config.getStringList("internet.blacklist").asScala.map(new Settings.AddressValidator(_)).toArray + val httpHostWhitelist = config.getStringList("internet.whitelist").asScala.map(new Settings.AddressValidator(_)).toArray val httpTimeout = (config.getInt("internet.requestTimeout") max 0) * 1000 val maxConnections = config.getInt("internet.maxTcpConnections") max 0 val internetThreads = config.getInt("internet.threads") max 1 @@ -319,14 +319,14 @@ class Settings(val config: Config) { // ----------------------------------------------------------------------- // // hologram - val hologramMaxScaleByTier = Array(config.getDoubleList("hologram.maxScale"): _*) match { + val hologramMaxScaleByTier = config.getDoubleList("hologram.maxScale").asScala.toArray match { case Array(tier1, tier2) => Array((tier1: Double) max 1.0, (tier2: Double) max 1.0) case _ => OpenComputers.log.warn("Bad number of hologram max scales, ignoring.") Array(3.0, 4.0) } - val hologramMaxTranslationByTier = Array(config.getDoubleList("hologram.maxTranslation"): _*) match { + val hologramMaxTranslationByTier = config.getDoubleList("hologram.maxTranslation").asScala.toArray match { case Array(tier1, tier2) => Array((tier1: Double) max 0.0, (tier2: Double) max 0.0) case _ => @@ -344,14 +344,14 @@ class Settings(val config: Config) { val maxNetworkPacketSize = config.getInt("misc.maxNetworkPacketSize") max 0 // Need at least 4 for nanomachine protocol. Because I can! val maxNetworkPacketParts = config.getInt("misc.maxNetworkPacketParts") max 4 - val maxOpenPorts = Array(config.getIntList("misc.maxOpenPorts"): _*) match { + val maxOpenPorts = config.getIntList("misc.maxOpenPorts").asScala.toArray match { case Array(wired, tier1, tier2) => Array((wired: Int) max 0, (tier1: Int) max 0, (tier2: Int) max 0) case _ => OpenComputers.log.warn("Bad number of max open ports, ignoring.") Array(16, 1, 16) } - val maxWirelessRange = Array(config.getDoubleList("misc.maxWirelessRange"): _*) match { + val maxWirelessRange = config.getDoubleList("misc.maxWirelessRange").asScala.toArray match { case Array(tier1, tier2) => Array((tier1: Double) max 0.0, (tier2: Double) max 0.0) case _ => @@ -455,8 +455,7 @@ class Settings(val config: Config) { case "true" | "allow" | java.lang.Boolean.TRUE => DebugCardAccess.Allowed case "false" | "deny" | java.lang.Boolean.FALSE => DebugCardAccess.Forbidden case "whitelist" => - val wlFile = new File(Loader.instance.getConfigDir + File.separator + "opencomputers" + File.separator + - "debug_card_whitelist.txt") + val wlFile = FMLPaths.CONFIGDIR.get.resolve(Paths.get("opencomputers", "debug_card_whitelist.txt")).toFile() DebugCardAccess.Whitelist(wlFile) @@ -472,7 +471,7 @@ class Settings(val config: Config) { val maxSignalQueueSize: Int = (if (config.hasPath("computer.maxSignalQueueSize")) config.getInt("computer.maxSignalQueueSize") else 256) min 256 // >= 1.7.6 - val vramSizes: Array[Double] = Array(config.getDoubleList("gpu.vramSizes"): _*) match { + val vramSizes: Array[Double] = config.getDoubleList("gpu.vramSizes").asScala.toArray match { case Array(tier1, tier2, tier3) => Array(tier1: Double, tier2: Double, tier3: Double) case _ => OpenComputers.log.warn("Bad number of VRAM sizes (expected 3), ignoring.") @@ -483,7 +482,7 @@ class Settings(val config: Config) { } object Settings { - val resourceDomain = "opencomputers" + val resourceDomain = OpenComputers.ID val namespace = "oc:" val savePath = "opencomputers/" val scriptPath: String = "/assets/" + resourceDomain + "/lua/" @@ -530,7 +529,6 @@ object Settings { try { val renderSettings = ConfigRenderOptions.defaults.setJson(false).setOriginComments(false) val nl = sys.props("line.separator") - val nle = StringEscapeUtils.escapeJava(nl) file.getParentFile.mkdirs() val out = new PrintWriter(file) out.write(config.root.render(renderSettings).lines. @@ -539,7 +537,7 @@ object Settings { // Finalize the string. filter(_ != "").mkString(nl). // Newline after values. - replaceAll(s"((?:\\s*#.*$nle)(?:\\s*[^#\\s].*$nle)+)", "$1" + nl)) + replaceAll(s"((?:\\s*#.*$nl)(?:\\s*[^#\\s].*$nl)+)", "$1" + nl)) out.close() } catch { @@ -572,12 +570,12 @@ object Settings { // created by) against the current version to see if some hard changes // were made. If so, the new default values are copied over. private def patchConfig(config: Config, defaults: Config) = { - val mod = Loader.instance.activeModContainer + val modVersion = OpenComputers.get.Version val prefix = "opencomputers." val configVersion = new DefaultArtifactVersion(if (config.hasPath(prefix + "version")) config.getString(prefix + "version") else "0.0.0") var patched = config - if (configVersion.compareTo(mod.getProcessedVersion) != 0) { - OpenComputers.log.info(s"Updating config from version '${configVersion.getVersionString}' to '${defaults.getString(prefix + "version")}'.") + if (configVersion.compareTo(modVersion) != 0) { + OpenComputers.log.info(s"Updating config from version '${configVersion}' to '${defaults.getString(prefix + "version")}'.") patched = patched.withValue(prefix + "version", defaults.getValue(prefix + "version")) for ((version, paths) <- configPatches if version.containsVersion(configVersion)) { for (path <- paths) { diff --git a/src/main/scala/li/cil/oc/client/ColorHandler.scala b/src/main/scala/li/cil/oc/client/ColorHandler.scala index 8430feda31..0ae6e82c10 100644 --- a/src/main/scala/li/cil/oc/client/ColorHandler.scala +++ b/src/main/scala/li/cil/oc/client/ColorHandler.scala @@ -8,15 +8,17 @@ import li.cil.oc.util.Color import li.cil.oc.util.ItemColorizer import li.cil.oc.util.ItemUtils import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.client.Minecraft import net.minecraft.client.renderer.color.IBlockColor import net.minecraft.client.renderer.color.IItemColor -import net.minecraft.item.EnumDyeColor +import net.minecraft.item.DyeColor import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.util.IItemProvider import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IBlockDisplayReader +import net.minecraft.world.IBlockReader object ColorHandler { def init(): Unit = { @@ -26,7 +28,7 @@ object ColorHandler { }, api.Items.get(Constants.BlockName.Cable).block()) - register((state, world, pos, tintIndex) => if (pos == null) 0xFFFFFFFF else world.getTileEntity(pos) match { + register((state, world, pos, tintIndex) => if (pos == null) 0xFFFFFFFF else world.getBlockEntity(pos) match { case colored: Colored => colored.getColor case _ => state.getBlock match { case block: block.Case => Color.rgbValues(Color.byTier(block.tier)) @@ -38,7 +40,7 @@ object ColorHandler { api.Items.get(Constants.BlockName.CaseTier3).block(), api.Items.get(Constants.BlockName.CaseCreative).block()) - register((state, world, pos, tintIndex) => Color.rgbValues(Color.byOreName(Color.dyes(state.getBlock.getMetaFromState(state) max 0 min Color.dyes.length))), + register((state, world, pos, tintIndex) => Color.rgbValues(state.getValue(block.ChameliumBlock.Color)), api.Items.get(Constants.BlockName.ChameliumBlock).block()) register((state, world, pos, tintIndex) => tintIndex, @@ -53,23 +55,23 @@ object ColorHandler { api.Items.get(Constants.BlockName.ScreenTier3).block()) register((stack, tintIndex) => if (ItemColorizer.hasColor(stack)) ItemColorizer.getColor(stack) else tintIndex, - Item.getItemFromBlock(api.Items.get(Constants.BlockName.Cable).block())) + api.Items.get(Constants.BlockName.Cable).block()) register((stack, tintIndex) => Color.rgbValues(Color.byTier(ItemUtils.caseTier(stack))), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.CaseTier1).block()), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.CaseTier2).block()), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.CaseTier3).block()), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.CaseCreative).block())) + api.Items.get(Constants.BlockName.CaseTier1).block(), + api.Items.get(Constants.BlockName.CaseTier2).block(), + api.Items.get(Constants.BlockName.CaseTier3).block(), + api.Items.get(Constants.BlockName.CaseCreative).block()) - register((stack, tintIndex) => Color.rgbValues(EnumDyeColor.byDyeDamage(stack.getItemDamage)), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.ChameliumBlock).block())) + register((stack, tintIndex) => Color.rgbValues(DyeColor.byId(stack.getDamageValue)), + api.Items.get(Constants.BlockName.ChameliumBlock).block()) register((stack, tintIndex) => tintIndex, - Item.getItemFromBlock(api.Items.get(Constants.BlockName.ScreenTier1).block()), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.ScreenTier2).block()), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.ScreenTier3).block()), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.Print).block()), - Item.getItemFromBlock(api.Items.get(Constants.BlockName.Robot).block())) + api.Items.get(Constants.BlockName.ScreenTier1).block(), + api.Items.get(Constants.BlockName.ScreenTier2).block(), + api.Items.get(Constants.BlockName.ScreenTier3).block(), + api.Items.get(Constants.BlockName.Print).block(), + api.Items.get(Constants.BlockName.Robot).block()) register((stack, tintIndex) => if (tintIndex == 1) { @@ -78,15 +80,15 @@ object ColorHandler { api.Items.get(Constants.ItemName.HoverBoots).item()) } - def register(handler: (IBlockState, IBlockAccess, BlockPos, Int) => Int, blocks: Block*): Unit = { - Minecraft.getMinecraft.getBlockColors.registerBlockColorHandler(new IBlockColor { - override def colorMultiplier(state: IBlockState, world: IBlockAccess, pos: BlockPos, tintIndex: Int): Int = handler(state, world, pos, tintIndex) + def register(handler: (BlockState, IBlockReader, BlockPos, Int) => Int, blocks: Block*): Unit = { + Minecraft.getInstance.getBlockColors.register(new IBlockColor { + override def getColor(state: BlockState, world: IBlockDisplayReader, pos: BlockPos, tintIndex: Int): Int = handler(state, world, pos, tintIndex) }, blocks: _*) } - def register(handler: (ItemStack, Int) => Int, items: Item*): Unit = { - Minecraft.getMinecraft.getItemColors.registerItemColorHandler(new IItemColor { - override def colorMultiplier(stack: ItemStack, tintIndex: Int): Int = handler(stack, tintIndex) + def register(handler: (ItemStack, Int) => Int, items: IItemProvider*): Unit = { + Minecraft.getInstance.getItemColors.register(new IItemColor { + override def getColor(stack: ItemStack, tintIndex: Int): Int = handler(stack, tintIndex) }, items: _*) } } diff --git a/src/main/scala/li/cil/oc/client/CommandHandler.scala b/src/main/scala/li/cil/oc/client/CommandHandler.scala deleted file mode 100644 index 6ea1bfb835..0000000000 --- a/src/main/scala/li/cil/oc/client/CommandHandler.scala +++ /dev/null @@ -1,32 +0,0 @@ -package li.cil.oc.client - -import li.cil.oc.common.command.SimpleCommand -import net.minecraft.client.gui.GuiScreen -import net.minecraft.command.ICommandSender -import net.minecraft.server.MinecraftServer -import net.minecraftforge.client.ClientCommandHandler - -object CommandHandler { - def register(): Unit = { - ClientCommandHandler.instance.registerCommand(SetClipboardCommand) - } - - object SetClipboardCommand extends SimpleCommand("oc_setclipboard") { - override def getUsage(source: ICommandSender): String = name + " " - - override def execute(server: MinecraftServer, source: ICommandSender, command: Array[String]): Unit = { - if (source.getEntityWorld.isRemote && command != null && command.length > 0) { - GuiScreen.setClipboardString(command(0)) - } - } - - // OP levels for reference: - // 1 - Ops can bypass spawn protection. - // 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks. - // 3 - Ops can use /ban, /deop, /kick, and /op. - // 4 - Ops can use /stop. - - override def getRequiredPermissionLevel = 0 - } - -} diff --git a/src/main/scala/li/cil/oc/client/ComponentTracker.scala b/src/main/scala/li/cil/oc/client/ComponentTracker.scala index 42a6950794..6cc54342dc 100644 --- a/src/main/scala/li/cil/oc/client/ComponentTracker.scala +++ b/src/main/scala/li/cil/oc/client/ComponentTracker.scala @@ -4,5 +4,5 @@ import li.cil.oc.common import net.minecraft.world.World object ComponentTracker extends common.ComponentTracker { - override protected def clear(world: World) = if (world.isRemote) super.clear(world) + override protected def clear(world: World) = if (world.isClientSide) super.clear(world) } diff --git a/src/main/scala/li/cil/oc/client/GuiHandler.scala b/src/main/scala/li/cil/oc/client/GuiHandler.scala deleted file mode 100644 index bf9736f932..0000000000 --- a/src/main/scala/li/cil/oc/client/GuiHandler.scala +++ /dev/null @@ -1,156 +0,0 @@ -package li.cil.oc.client - -import com.google.common.base.Strings -import li.cil.oc.Localization -import li.cil.oc.Settings -import li.cil.oc.api -import li.cil.oc.common.GuiType -import li.cil.oc.common.component -import li.cil.oc.common.entity -import li.cil.oc.common.inventory.{DatabaseInventory, DiskDriveMountableInventory, ServerInventory} -import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator -import li.cil.oc.common.tileentity -import li.cil.oc.common.{GuiHandler => CommonGuiHandler} -import li.cil.oc.util.BlockPosition -import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.client.Minecraft -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.tileentity.TileEntity -import net.minecraft.world.World -import net.minecraft.item.ItemStack - -object GuiHandler extends CommonGuiHandler { - override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef = { - GuiType.Categories.get(id) match { - case Some(GuiType.Category.Block) => - world.getTileEntity(BlockPosition(x, GuiType.extractY(y), z)) match { - case t: tileentity.Adapter if id == GuiType.Adapter.id => - new gui.Adapter(player.inventory, t) - case t: tileentity.Assembler if id == GuiType.Assembler.id => - new gui.Assembler(player.inventory, t) - case t: tileentity.Case if id == GuiType.Case.id => - new gui.Case(player.inventory, t) - case t: tileentity.Charger if id == GuiType.Charger.id => - new gui.Charger(player.inventory, t) - case t: tileentity.Disassembler if id == GuiType.Disassembler.id => - new gui.Disassembler(player.inventory, t) - case t: tileentity.DiskDrive if id == GuiType.DiskDrive.id => - new gui.DiskDrive(player.inventory, t) - case t: tileentity.Printer if id == GuiType.Printer.id => - new gui.Printer(player.inventory, t) - case t: tileentity.Rack if id == GuiType.Rack.id => - new gui.Rack(player.inventory, t) - case t: tileentity.Raid if id == GuiType.Raid.id => - new gui.Raid(player.inventory, t) - case t: tileentity.Relay if id == GuiType.Relay.id => - new gui.Relay(player.inventory, t) - case t: tileentity.RobotProxy if id == GuiType.Robot.id => - new gui.Robot(player.inventory, t.robot) - case t: tileentity.Screen if id == GuiType.Screen.id => - new gui.Screen(t.origin.buffer, t.tier > 0, () => t.origin.hasKeyboard, () => t.origin.buffer.isRenderingEnabled) - case t: tileentity.Rack if id == GuiType.ServerInRack.id => - val slot = GuiType.extractSlot(y) - new gui.Server(player.inventory, new ServerInventory { - override def container = t.getStackInSlot(slot) - - override def isUsableByPlayer(player: EntityPlayer) = t.isUsableByPlayer(player) - }, Option(t), slot) - case t: tileentity.Rack if id == GuiType.DiskDriveMountableInRack.id => - val slot = GuiType.extractSlot(y) - new gui.DiskDrive(player.inventory, new DiskDriveMountableInventory { - override def container: ItemStack = t.getStackInSlot(slot) - - override def isUsableByPlayer(player: EntityPlayer): Boolean = t.isUsableByPlayer(player) - }) - case t: tileentity.Waypoint if id == GuiType.Waypoint.id => - new gui.Waypoint(t) - case _ => null - } - case Some(GuiType.Category.Entity) => - world.getEntityByID(x) match { - case drone: entity.Drone if id == GuiType.Drone.id => - new gui.Drone(player.inventory, drone) - case _ => null - } - case Some(GuiType.Category.Item) => { - val itemStackInUse = getItemStackInUse(id, player) - Delegator.subItem(itemStackInUse) match { - case Some(drive: item.traits.FileSystemLike) if id == GuiType.Drive.id => - new gui.Drive(player.inventory, () => itemStackInUse) - case Some(database: item.UpgradeDatabase) if id == GuiType.Database.id => - new gui.Database(player.inventory, new DatabaseInventory { - override def container = itemStackInUse - - override def isUsableByPlayer(player: EntityPlayer) = player == player - }) - case Some(server: item.Server) if id == GuiType.Server.id => - new gui.Server(player.inventory, new ServerInventory { - override def container = itemStackInUse - - override def isUsableByPlayer(player: EntityPlayer) = player == player - }) - case Some(tablet: item.Tablet) if id == GuiType.Tablet.id => - val stack = itemStackInUse - if (stack.hasTagCompound) { - item.Tablet.get(stack, player).components.collect { - case Some(buffer: api.internal.TextBuffer) => buffer - }.headOption match { - case Some(buffer: api.internal.TextBuffer) => new gui.Screen(buffer, true, () => true, () => buffer.isRenderingEnabled) - case _ => null - } - } - else null - case Some(tablet: item.Tablet) if id == GuiType.TabletInner.id => - val stack = itemStackInUse - if (stack.hasTagCompound) { - new gui.Tablet(player.inventory, item.Tablet.get(stack, player)) - } - else null - case Some(_: item.DiskDriveMountable) if id == GuiType.DiskDriveMountable.id => - new gui.DiskDrive(player.inventory, new DiskDriveMountableInventory { - override def container = itemStackInUse - override def isUsableByPlayer(activePlayer : EntityPlayer): Boolean = activePlayer == player - }) - case Some(terminal: item.Terminal) if id == GuiType.Terminal.id => - val stack = itemStackInUse - if (stack.hasTagCompound) { - val address = stack.getTagCompound.getString(Settings.namespace + "server") - val key = stack.getTagCompound.getString(Settings.namespace + "key") - if (!Strings.isNullOrEmpty(key) && !Strings.isNullOrEmpty(address)) { - component.TerminalServer.loaded.find(address) match { - case Some(term) if term != null && term.rack != null => term.rack match { - case rack: TileEntity with api.internal.Rack => - def inRange = player.isEntityAlive && !rack.isInvalid && rack.getDistanceSq(player.posX, player.posY, player.posZ) < term.range * term.range - if (inRange) { - if (term.sidedKeys.contains(key)) return new gui.Screen(term.buffer, true, () => true, () => { - // Check if someone else bound a term to our server. - if (stack.getTagCompound.getString(Settings.namespace + "key") != key) { - Minecraft.getMinecraft.displayGuiScreen(null) - } - // Check whether we're still in range. - if (!inRange) { - Minecraft.getMinecraft.displayGuiScreen(null) - } - true - }) - else player.sendMessage(Localization.Terminal.InvalidKey) - } - else player.sendMessage(Localization.Terminal.OutOfRange) - case _ => // Eh? - } - case _ => player.sendMessage(Localization.Terminal.OutOfRange) - } - } - } - null - case _ => null - } - } - case Some(GuiType.Category.None) => - if (id == GuiType.Manual.id) new gui.Manual() - else null - case _ => null - } - } -} diff --git a/src/main/scala/li/cil/oc/client/KeyBindings.scala b/src/main/scala/li/cil/oc/client/KeyBindings.scala index 688a1a9491..f357ff7cb1 100644 --- a/src/main/scala/li/cil/oc/client/KeyBindings.scala +++ b/src/main/scala/li/cil/oc/client/KeyBindings.scala @@ -1,44 +1,56 @@ package li.cil.oc.client import li.cil.oc.OpenComputers -import net.minecraft.client.settings.GameSettings +import li.cil.oc.client.gui.traits.InputBuffer +import net.minecraft.client.Minecraft import net.minecraft.client.settings.KeyBinding -import net.minecraftforge.fml.client.FMLClientHandler -import org.lwjgl.input.Keyboard -import org.lwjgl.input.Mouse +import net.minecraft.client.util.InputMappings +import net.minecraftforge.client.settings.IKeyConflictContext +import net.minecraftforge.client.settings.KeyConflictContext +import net.minecraftforge.client.settings.KeyModifier +import org.lwjgl.glfw.GLFW import scala.collection.mutable object KeyBindings { - val keyBindingChecks = mutable.ArrayBuffer(isKeyBindingPressedVanilla _) - - val keyBindingNameGetters = mutable.ArrayBuffer(getKeyBindingNameVanilla _) + private def isActive(input: InputMappings.Input): Boolean = { + val window = Minecraft.getInstance.getWindow.getWindow + input.getType match { + case InputMappings.Type.MOUSE => GLFW.glfwGetMouseButton(window, input.getValue) == GLFW.GLFW_PRESS + case InputMappings.Type.SCANCODE => false // GLFW doesn't have a glfwGetScancode method to test these. + case InputMappings.Type.KEYSYM => GLFW.glfwGetKey(window, input.getValue) == GLFW.GLFW_PRESS + } + } - def showExtendedTooltips: Boolean = isKeyBindingPressed(extendedTooltip) + def showExtendedTooltips: Boolean = { + if (extendedTooltip.isDown) return true + // We have to know if the keybind is pressed even if the active screen doesn't pass events. + if (!extendedTooltip.getKeyConflictContext.isActive) return false + if (extendedTooltip.getKey == InputMappings.UNKNOWN) return false + extendedTooltip.getKeyModifier match { + // KeyModifier.NONE does not accept pure modifier keys by default, so check for that. + case KeyModifier.NONE if KeyModifier.isKeyCodeModifier(extendedTooltip.getKey) => isActive(extendedTooltip.getKey) + case mod if mod.isActive(extendedTooltip.getKeyConflictContext) => isActive(extendedTooltip.getKey) + case _ => false + } + } - def isPastingClipboard: Boolean = isKeyBindingPressed(clipboardPaste) + def isAnalyzeCopyingAddress: Boolean = analyzeCopyAddr.isDown - def getKeyBindingName(keyBinding: KeyBinding): String = keyBindingNameGetters.map(_ (keyBinding)).collectFirst { - case Some(name) => name - }.getOrElse("???") + def getKeyBindingName(keyBinding: KeyBinding) = keyBinding.getTranslatedKeyMessage.getString - def isKeyBindingPressed(keyBinding: KeyBinding): Boolean = keyBindingChecks.forall(_ (keyBinding)) + val textInputConflict = new IKeyConflictContext { + override def isActive: Boolean = Minecraft.getInstance.screen.isInstanceOf[InputBuffer] - def getKeyBindingNameVanilla(keyBinding: KeyBinding): Option[String] = try Some(GameSettings.getKeyDisplayString(keyBinding.getKeyCode)) catch { - case _: Throwable => None + override def conflicts(other: IKeyConflictContext): Boolean = this == other } - def isKeyBindingPressedVanilla(keyBinding: KeyBinding): Boolean = try { - if (keyBinding.getKeyCode < 0) - Mouse.isCreated && Mouse.isButtonDown(keyBinding.getKeyCode + 100) - else - Keyboard.isCreated && Keyboard.isKeyDown(keyBinding.getKeyCode) - } - catch { - case _: Throwable => false - } + val extendedTooltip = new KeyBinding("key.opencomputers.extendedTooltip", KeyConflictContext.GUI, + InputMappings.Type.KEYSYM, GLFW.GLFW_KEY_LEFT_SHIFT, OpenComputers.Name) - def extendedTooltip: KeyBinding = FMLClientHandler.instance.getClient.gameSettings.keyBindSneak + val analyzeCopyAddr = new KeyBinding("key.opencomputers.analyzeCopyAddress", KeyConflictContext.IN_GAME, + InputMappings.Type.KEYSYM, GLFW.GLFW_KEY_LEFT_CONTROL, OpenComputers.Name) - val clipboardPaste = new KeyBinding("key.clipboardPaste", Keyboard.KEY_INSERT, OpenComputers.Name) + val clipboardPaste = new KeyBinding("key.opencomputers.clipboardPaste", textInputConflict, + InputMappings.Type.KEYSYM, GLFW.GLFW_KEY_INSERT, OpenComputers.Name) } diff --git a/src/main/scala/li/cil/oc/client/Manual.scala b/src/main/scala/li/cil/oc/client/Manual.scala index a0e81fb297..38644b5ec0 100644 --- a/src/main/scala/li/cil/oc/client/Manual.scala +++ b/src/main/scala/li/cil/oc/client/Manual.scala @@ -8,23 +8,22 @@ import li.cil.oc.api.manual.ImageProvider import li.cil.oc.api.manual.ImageRenderer import li.cil.oc.api.manual.PathProvider import li.cil.oc.api.manual.TabIconRenderer -import li.cil.oc.common.GuiType import net.minecraft.client.Minecraft -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import net.minecraftforge.fml.common.FMLCommonHandler import scala.annotation.tailrec -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object Manual extends ManualAPI { final val LanguageKey = "%LANGUAGE%" - final val FallbackLanguage = "en_US" + final val FallbackLanguage = "en_us" class History(val path: String, var offset: Int = 0) @@ -38,7 +37,7 @@ object Manual extends ManualAPI { val imageProviders = mutable.Buffer.empty[(String, ImageProvider)] - val history = new mutable.Stack[History] + val history = new mutable.ArrayStack[History] reset() @@ -87,7 +86,7 @@ object Manual extends ManualAPI { override def contentFor(path: String): java.lang.Iterable[String] = { val cleanPath = com.google.common.io.Files.simplifyPath(path) - val language = FMLCommonHandler.instance.getCurrentLanguage + val language = Minecraft.getInstance().getLanguageManager().getSelected().getCode() contentForWithRedirects(cleanPath.replaceAll(LanguageKey, language)). orElse(contentForWithRedirects(cleanPath.replaceAll(LanguageKey, FallbackLanguage))). orNull @@ -107,9 +106,10 @@ object Manual extends ManualAPI { null } - override def openFor(player: EntityPlayer): Unit = { - if (player.getEntityWorld.isRemote) { - player.openGui(OpenComputers, GuiType.Manual.id, player.getEntityWorld, 0, 0, 0) + override def openFor(player: PlayerEntity): Unit = { + if (player.level.isClientSide) { + val mc = Minecraft.getInstance + if (player == mc.player) mc.pushGuiLayer(new gui.Manual()) } } @@ -119,7 +119,7 @@ object Manual extends ManualAPI { } override def navigate(path: String): Unit = { - Minecraft.getMinecraft.currentScreen match { + Minecraft.getInstance.screen match { case manual: gui.Manual => manual.pushPage(path) case _ => history.push(new History(path)) } diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index 9cf0b967ab..327f0e1c9b 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -1,7 +1,10 @@ package li.cil.oc.client import java.io.EOFException +import java.io.InputStream +import com.mojang.blaze3d.systems.IRenderCall +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.OpenComputers import li.cil.oc.Settings @@ -23,32 +26,25 @@ import li.cil.oc.integration.jei.ModJEI import li.cil.oc.util.Audio import li.cil.oc.util.ExtendedWorld._ import net.minecraft.client.Minecraft -import net.minecraft.client.gui.GuiScreen -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumParticleTypes +import net.minecraft.particles.IParticleData +import net.minecraft.util.Direction +import net.minecraft.util.Util import net.minecraft.util.ResourceLocation import net.minecraft.util.SoundCategory import net.minecraft.util.SoundEvent -import net.minecraft.util.math.Vec3d +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.util.text.ChatType import net.minecraft.world.World import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.fml.common.Optional -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent -import org.lwjgl.input.Keyboard +import net.minecraftforge.registries.ForgeRegistries object PacketHandler extends CommonPacketHandler { - @SubscribeEvent - def onPacket(e: ClientCustomPacketEvent): Unit = { - onPacketData(e.getManager.getNetHandler, e.getPacket.payload, Minecraft.getMinecraft.player) - } - - protected override def world(player: EntityPlayer, dimension: Int): Option[World] = { - val world = player.world - if (world.provider.getDimension == dimension) Some(world) + protected override def world(player: PlayerEntity, dimension: ResourceLocation): Option[World] = { + val world = player.level + if (world.dimension.location.equals(dimension)) Some(world) else None } @@ -115,23 +111,28 @@ object PacketHandler extends CommonPacketHandler { } def onAdapterState(p: PacketParser): Unit = - p.readTileEntity[Adapter]() match { + p.readBlockEntity[Adapter]() match { case Some(t) => t.openSides = t.uncompressSides(p.readByte()) - t.world.notifyBlockUpdate(t.getPos) + t.world.notifyBlockUpdate(t.getBlockPos) case _ => // Invalid packet. } def onAnalyze(p: PacketParser) { val address = p.readUTF() - if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) { - GuiScreen.setClipboardString(address) - p.player.sendMessage(Localization.Analyzer.AddressCopied) + if (KeyBindings.isAnalyzeCopyingAddress) { + RenderSystem.recordRenderCall(new IRenderCall { + override def execute = { + val mc = Minecraft.getInstance + mc.keyboardHandler.setClipboard(address) + mc.gui.handleChat(ChatType.SYSTEM, Localization.Analyzer.AddressCopied, Util.NIL_UUID) + } + }) } } def onChargerState(p: PacketParser): Unit = - p.readTileEntity[Charger]() match { + p.readBlockEntity[Charger]() match { case Some(t) => t.chargeSpeed = p.readDouble() t.hasPower = p.readBoolean() @@ -144,14 +145,17 @@ object PacketHandler extends CommonPacketHandler { } def onClipboard(p: PacketParser) { - GuiScreen.setClipboardString(p.readUTF()) + val contents = p.readUTF() + RenderSystem.recordRenderCall(new IRenderCall { + override def execute = Minecraft.getInstance.keyboardHandler.setClipboard(contents) + }) } def onColorChange(p: PacketParser): Unit = - p.readTileEntity[Colored]() match { + p.readBlockEntity[Colored]() match { case Some(t) => t.setColor(p.readInt()) - t.getWorld.notifyBlockUpdate(t.position) + t.getLevel.notifyBlockUpdate(t.position) case _ => // Invalid packet. } @@ -165,7 +169,7 @@ object PacketHandler extends CommonPacketHandler { } def onComputerState(p: PacketParser): Unit = - p.readTileEntity[Computer]() match { + p.readBlockEntity[Computer]() match { case Some(t) => t.setRunning(p.readBoolean()) t.hasErrored = p.readBoolean() @@ -173,7 +177,7 @@ object PacketHandler extends CommonPacketHandler { } def onComputerUserList(p: PacketParser): Unit = - p.readTileEntity[Computer]() match { + p.readBlockEntity[Computer]() match { case Some(t) => val count = p.readInt() t.setUsers((0 until count).map(_ => p.readUTF())) @@ -181,9 +185,9 @@ object PacketHandler extends CommonPacketHandler { } def onContainerUpdate(p: PacketParser): Unit = { - val windowId = p.readUnsignedByte() - if (p.player.openContainer != null && p.player.openContainer.windowId == windowId) { - p.player.openContainer match { + val containerId = p.readInt() + if (p.player.containerMenu != null && p.player.containerMenu.containerId == containerId) { + p.player.containerMenu match { case container: container.Player => container.updateCustomData(p.readNBT()) case _ => // Invalid packet. } @@ -191,7 +195,7 @@ object PacketHandler extends CommonPacketHandler { } def onDisassemblerActiveChange(p: PacketParser): Unit = - p.readTileEntity[Disassembler]() match { + p.readBlockEntity[Disassembler]() match { case Some(t) => t.isActive = p.readBoolean() case _ => // Invalid packet. } @@ -199,12 +203,12 @@ object PacketHandler extends CommonPacketHandler { def onFileSystemActivity(p: PacketParser): AnyVal = { val sound = p.readUTF() val data = CompressedStreamTools.read(p) - if (p.readBoolean()) p.readTileEntity[net.minecraft.tileentity.TileEntity]() match { + if (p.readBoolean()) p.readBlockEntity[net.minecraft.tileentity.TileEntity]() match { case Some(t) => MinecraftForge.EVENT_BUS.post(new FileSystemAccessEvent.Client(sound, t, data)) case _ => // Invalid packet. } - else world(p.player, p.readInt()) match { + else world(p.player, new ResourceLocation(p.readUTF())) match { case Some(world) => val x = p.readDouble() val y = p.readDouble() @@ -216,12 +220,12 @@ object PacketHandler extends CommonPacketHandler { def onNetworkActivity(p: PacketParser): AnyVal = { val data = CompressedStreamTools.read(p) - if (p.readBoolean()) p.readTileEntity[net.minecraft.tileentity.TileEntity]() match { + if (p.readBoolean()) p.readBlockEntity[net.minecraft.tileentity.TileEntity]() match { case Some(t) => MinecraftForge.EVENT_BUS.post(new NetworkActivityEvent.Client(t, data)) case _ => // Invalid packet. } - else world(p.player, p.readInt()) match { + else world(p.player, new ResourceLocation(p.readUTF())) match { case Some(world) => val x = p.readDouble() val y = p.readDouble() @@ -232,13 +236,13 @@ object PacketHandler extends CommonPacketHandler { } def onFloppyChange(p: PacketParser): Unit = - p.readTileEntity[DiskDrive]() match { - case Some(t) => t.setInventorySlotContents(0, p.readItemStack()) + p.readBlockEntity[DiskDrive]() match { + case Some(t) => t.setItem(0, p.readItemStack()) case _ => // Invalid packet. } def onHologramClear(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => for (i <- t.volume.indices) t.volume(i) = 0 t.needsRendering = true @@ -246,7 +250,7 @@ object PacketHandler extends CommonPacketHandler { } def onHologramColor(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => val index = p.readInt() val value = p.readInt() @@ -256,20 +260,20 @@ object PacketHandler extends CommonPacketHandler { } def onHologramPowerChange(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => t.hasPower = p.readBoolean() case _ => // Invalid packet. } def onHologramScale(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => t.scale = p.readDouble() case _ => // Invalid packet. } def onHologramArea(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => val fromX = p.readByte(): Int val untilX = p.readByte(): Int @@ -286,7 +290,7 @@ object PacketHandler extends CommonPacketHandler { } def onHologramValues(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => val count = p.readInt() for (i <- 0 until count) { @@ -301,17 +305,17 @@ object PacketHandler extends CommonPacketHandler { } def onHologramPositionOffsetY(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => val x = p.readDouble() val y = p.readDouble() val z = p.readDouble() - t.translation = new Vec3d(x, y, z) + t.translation = new Vector3d(x, y, z) case _ => // Invalid packet. } def onHologramRotation(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => t.rotationAngle = p.readFloat() t.rotationX = p.readFloat() @@ -321,7 +325,7 @@ object PacketHandler extends CommonPacketHandler { } def onHologramRotationSpeed(p: PacketParser): Unit = - p.readTileEntity[Hologram]() match { + p.readBlockEntity[Hologram]() match { case Some(t) => t.rotationSpeed = p.readFloat() t.rotationSpeedX = p.readFloat() @@ -336,15 +340,10 @@ object PacketHandler extends CommonPacketHandler { Loot.disksForClient += stack } if(Mods.JustEnoughItems.isModAvailable) { - addDiskToJEI(stack) + ModJEI.addDiskAtRuntime(stack) } } - @Optional.Method(modid = Mods.IDs.JustEnoughItems) - private def addDiskToJEI(stack: ItemStack): Unit = { - ModJEI.addDiskAtRuntime(stack) - } - def onCyclingDisk(p: PacketParser): Any = { val stack = p.readItemStack() if (!stack.isEmpty) { @@ -353,12 +352,12 @@ object PacketHandler extends CommonPacketHandler { } def onNanomachinesConfiguration(p: PacketParser): Unit = { - p.readEntity[EntityPlayer]() match { + p.readEntity[PlayerEntity]() match { case Some(player) => val hasController = p.readBoolean() if (hasController) { api.Nanomachines.installController(player) match { - case controller: ControllerImpl => controller.load(p.readNBT()) + case controller: ControllerImpl => controller.loadData(p.readNBT()) case _ => // Wat. } } @@ -370,7 +369,7 @@ object PacketHandler extends CommonPacketHandler { } def onNanomachinesInputs(p: PacketParser): Unit = { - p.readEntity[EntityPlayer]() match { + p.readEntity[PlayerEntity]() match { case Some(player) => api.Nanomachines.getController(player) match { case controller: ControllerImpl => val inputs = new Array[Byte](p.readInt()) @@ -388,7 +387,7 @@ object PacketHandler extends CommonPacketHandler { } def onNanomachinesPower(p: PacketParser): Unit = { - p.readEntity[EntityPlayer]() match { + p.readEntity[PlayerEntity]() match { case Some(player) => api.Nanomachines.getController(player) match { case controller: ControllerImpl => controller.storedEnergy = p.readDouble() case _ => // Wat. @@ -398,45 +397,47 @@ object PacketHandler extends CommonPacketHandler { } def onNetSplitterState(p: PacketParser): Unit = - p.readTileEntity[NetSplitter]() match { + p.readBlockEntity[NetSplitter]() match { case Some(t) => t.isInverted = p.readBoolean() t.openSides = t.uncompressSides(p.readByte()) - t.world.notifyBlockUpdate(t.getPos) + t.world.notifyBlockUpdate(t.getBlockPos) case _ => // Invalid packet. } def onParticleEffect(p: PacketParser): Unit = { - val dimension = p.readInt() - world(p.player, dimension) match { + world(p.player, new ResourceLocation(p.readUTF())) match { case Some(world) => val x = p.readInt() val y = p.readInt() val z = p.readInt() val velocity = p.readDouble() val direction = p.readDirection() - val particleType = EnumParticleTypes.getParticleFromId(p.readInt()) - val count = p.readUnsignedByte() - - for (i <- 0 until count) { - def rv(f: EnumFacing => Int) = direction match { - case Some(d) => world.rand.nextFloat - 0.5 + f(d) * 0.5 - case _ => world.rand.nextFloat * 2.0 - 1 - } - - val vx = rv(_.getFrontOffsetX) - val vy = rv(_.getFrontOffsetY) - val vz = rv(_.getFrontOffsetZ) - if (vx * vx + vy * vy + vz * vz < 1) { - def rp(x: Int, v: Double, f: EnumFacing => Int) = direction match { - case Some(d) => x + 0.5 + v * velocity * 0.5 + f(d) * velocity - case _ => x + 0.5 + v * velocity + val particleType = p.readRegistryEntry(ForgeRegistries.PARTICLE_TYPES) + if (particleType.isInstanceOf[IParticleData]) { + val particle = particleType.asInstanceOf[IParticleData] + val count = p.readUnsignedByte() + + for (i <- 0 until count) { + def rv(f: Direction => Int) = direction match { + case Some(d) => world.random.nextFloat - 0.5 + f(d) * 0.5 + case _ => world.random.nextFloat * 2.0 - 1 } - val px = rp(x, vx, _.getFrontOffsetX) - val py = rp(y, vy, _.getFrontOffsetY) - val pz = rp(z, vz, _.getFrontOffsetZ) - world.spawnParticle(particleType, px, py, pz, vx, vy + velocity * 0.25, vz) + val vx = rv(_.getStepX) + val vy = rv(_.getStepY) + val vz = rv(_.getStepZ) + if (vx * vx + vy * vy + vz * vz < 1) { + def rp(x: Int, v: Double, f: Direction => Int) = direction match { + case Some(d) => x + 0.5 + v * velocity * 0.5 + f(d) * velocity + case _ => x + 0.5 + v * velocity + } + + val px = rp(x, vx, _.getStepX) + val py = rp(y, vy, _.getStepY) + val pz = rp(z, vz, _.getStepZ) + world.addParticle(particle, px, py, pz, vx, vy + velocity * 0.25, vz) + } } } case _ => // Invalid packet. @@ -447,7 +448,7 @@ object PacketHandler extends CommonPacketHandler { if (!PetRenderer.isInitialized) { PetRenderer.isInitialized = true if (Settings.get.hideOwnPet) { - PetRenderer.hidden += Minecraft.getMinecraft.player.getName + PetRenderer.hidden += Minecraft.getInstance.player.getName.getString } PacketSender.sendPetVisibility() } @@ -465,7 +466,7 @@ object PacketHandler extends CommonPacketHandler { } def onPowerState(p: PacketParser): Unit = - p.readTileEntity[PowerInformation]() match { + p.readBlockEntity[PowerInformation]() match { case Some(t) => t.globalBuffer = p.readDouble() t.globalBufferSize = p.readDouble() @@ -473,7 +474,7 @@ object PacketHandler extends CommonPacketHandler { } def onPrinterState(p: PacketParser): Unit = - p.readTileEntity[Printer]() match { + p.readBlockEntity[Printer]() match { case Some(t) => if (p.readBoolean()) t.requiredEnergy = 9001 else t.requiredEnergy = 0 @@ -481,58 +482,58 @@ object PacketHandler extends CommonPacketHandler { } def onRackInventory(p: PacketParser): Unit = - p.readTileEntity[Rack]() match { + p.readBlockEntity[Rack]() match { case Some(t) => val count = p.readInt() for (_ <- 0 until count) { val slot = p.readInt() - t.setInventorySlotContents(slot, p.readItemStack()) + t.setItem(slot, p.readItemStack()) } case _ => // Invalid packet. } def onRackMountableData(p: PacketParser): Unit = - p.readTileEntity[Rack]() match { + p.readBlockEntity[Rack]() match { case Some(t) => val mountableIndex = p.readInt() t.lastData(mountableIndex) = p.readNBT() - t.getWorld.notifyBlockUpdate(t.getPos) + t.getLevel.notifyBlockUpdate(t.getBlockPos) case _ => // Invalid packet. } def onRaidStateChange(p: PacketParser): Unit = - p.readTileEntity[Raid]() match { + p.readBlockEntity[Raid]() match { case Some(t) => - for (slot <- 0 until t.getSizeInventory) { + for (slot <- 0 until t.getContainerSize) { t.presence(slot) = p.readBoolean() } case _ => // Invalid packet. } def onRedstoneState(p: PacketParser): Unit = - p.readTileEntity[RedstoneAware]() match { + p.readBlockEntity[RedstoneAware]() match { case Some(t) => t.setOutputEnabled(p.readBoolean()) - for (d <- EnumFacing.values) { + for (d <- Direction.values) { t.setOutput(d, p.readByte()) } case _ => // Invalid packet. } def onRobotAnimateSwing(p: PacketParser): Unit = - p.readTileEntity[RobotProxy]() match { + p.readBlockEntity[RobotProxy]() match { case Some(t) => t.robot.setAnimateSwing(p.readInt()) case _ => // Invalid packet. } def onRobotAnimateTurn(p: PacketParser): Unit = - p.readTileEntity[RobotProxy]() match { + p.readBlockEntity[RobotProxy]() match { case Some(t) => t.robot.setAnimateTurn(p.readByte(), p.readInt()) case _ => // Invalid packet. } def onRobotAssemblingState(p: PacketParser): Unit = - p.readTileEntity[Assembler]() match { + p.readBlockEntity[Assembler]() match { case Some(t) => if (p.readBoolean()) t.requiredEnergy = 9001 else t.requiredEnergy = 0 @@ -540,26 +541,26 @@ object PacketHandler extends CommonPacketHandler { } def onRobotInventoryChange(p: PacketParser): Unit = - p.readTileEntity[RobotProxy]() match { + p.readBlockEntity[RobotProxy]() match { case Some(t) => val robot = t.robot val slot = p.readInt() val stack = p.readItemStack() - if (slot >= robot.getSizeInventory - robot.componentCount) { - robot.info.components(slot - (robot.getSizeInventory - robot.componentCount)) = stack + if (slot >= robot.getContainerSize - robot.componentCount) { + robot.info.components(slot - (robot.getContainerSize - robot.componentCount)) = stack } - else t.robot.setInventorySlotContents(slot, stack) + else t.robot.setItem(slot, stack) case _ => // Invalid packet. } def onRobotLightChange(p: PacketParser): Unit = - p.readTileEntity[RobotProxy]() match { + p.readBlockEntity[RobotProxy]() match { case Some(t) => t.robot.info.lightColor = p.readInt() case _ => // Invalid packet. } def onRobotNameChange(p: PacketParser) = { - p.readTileEntity[RobotProxy]() match { + p.readBlockEntity[RobotProxy]() match { case Some(t) => { val len = p.readShort() val name = new Array[Char](len) @@ -573,28 +574,28 @@ object PacketHandler extends CommonPacketHandler { } def onRobotMove(p: PacketParser): AnyVal = { - val dimension = p.readInt() + val dimension = new ResourceLocation(p.readUTF()) val x = p.readInt() val y = p.readInt() val z = p.readInt() val direction = p.readDirection() - (p.getTileEntity[RobotProxy](dimension, x, y, z), direction) match { + (p.getBlockEntity[RobotProxy](dimension, x, y, z), direction) match { case (Some(t), Some(d)) => t.robot.move(d) case (_, Some(d)) => // Invalid packet, robot may be coming from outside our loaded area. - PacketSender.sendRobotStateRequest(dimension, x + d.getFrontOffsetX, y + d.getFrontOffsetY, z + d.getFrontOffsetZ) + PacketSender.sendRobotStateRequest(dimension, x + d.getStepX, y + d.getStepY, z + d.getStepZ) case _ => // Invalid packet. } } def onRobotSelectedSlotChange(p: PacketParser): Unit = - p.readTileEntity[RobotProxy]() match { + p.readBlockEntity[RobotProxy]() match { case Some(t) => t.robot.selectedSlot = p.readInt() case _ => // Invalid packet. } def onRotatableState(p: PacketParser): Unit = - p.readTileEntity[Rotatable]() match { + p.readBlockEntity[Rotatable]() match { case Some(t) => t.pitch = p.readDirection().get t.yaw = p.readDirection().get @@ -602,41 +603,41 @@ object PacketHandler extends CommonPacketHandler { } def onSwitchActivity(p: PacketParser): Unit = - p.readTileEntity[Relay]() match { + p.readBlockEntity[Relay]() match { case Some(t) => t.lastMessage = System.currentTimeMillis() case _ => // Invalid packet. } def onTextBufferPowerChange(p: PacketParser): Unit = - ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match { + ComponentTracker.get(p.player.level, p.readUTF()) match { case Some(buffer: api.internal.TextBuffer) => buffer.setRenderingEnabled(p.readBoolean()) case _ => // Invalid packet. } def onTextBufferInit(p: PacketParser) { - ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match { + ComponentTracker.get(p.player.level, p.readUTF()) match { case Some(buffer: li.cil.oc.common.component.TextBuffer) => val nbt = p.readNBT() - if (nbt.hasKey("maxWidth")) { - val maxWidth = nbt.getInteger("maxWidth") - val maxHeight = nbt.getInteger("maxHeight") + if (nbt.contains("maxWidth")) { + val maxWidth = nbt.getInt("maxWidth") + val maxHeight = nbt.getInt("maxHeight") buffer.setMaximumResolution(maxWidth, maxHeight) } - buffer.data.load(nbt) - if (nbt.hasKey("viewportWidth")) { - val viewportWidth = nbt.getInteger("viewportWidth") - val viewportHeight = nbt.getInteger("viewportHeight") + buffer.data.loadData(nbt) + if (nbt.contains("viewportWidth")) { + val viewportWidth = nbt.getInt("viewportWidth") + val viewportHeight = nbt.getInt("viewportHeight") buffer.setViewport(viewportWidth, viewportHeight) } - buffer.proxy.markDirty() + buffer.proxy.setChanged() buffer.markInitialized() case _ => // Invalid packet. } } def onTextBufferMulti(p: PacketParser): Unit = - if (p.player != null) ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match { + if (p.player != null) ComponentTracker.get(p.player.level, p.readUTF()) match { case Some(buffer: api.internal.TextBuffer) => try while (true) { p.readPacketType() match { @@ -815,14 +816,13 @@ object PacketHandler extends CommonPacketHandler { } def onScreenTouchMode(p: PacketParser): Unit = - p.readTileEntity[Screen]() match { + p.readBlockEntity[Screen]() match { case Some(t) => t.invertTouchMode = p.readBoolean() case _ => // Invalid packet. } def onSoundEffect(p: PacketParser) { - val dimension = p.readInt() - world(p.player, dimension) match { + world(p.player, new ResourceLocation(p.readUTF())) match { case Some(world) => val x = p.readDouble() val y = p.readDouble() @@ -836,8 +836,7 @@ object PacketHandler extends CommonPacketHandler { } def onSound(p: PacketParser) { - val dimension = p.readInt() - if (world(p.player, dimension).isDefined) { + if (world(p.player, new ResourceLocation(p.readUTF())).isDefined) { val x = p.readInt() val y = p.readInt() val z = p.readInt() @@ -848,8 +847,7 @@ object PacketHandler extends CommonPacketHandler { } def onSoundPattern(p: PacketParser) { - val dimension = p.readInt() - if (world(p.player, dimension).isDefined) { + if (world(p.player, new ResourceLocation(p.readUTF())).isDefined) { val x = p.readInt() val y = p.readInt() val z = p.readInt() @@ -859,14 +857,16 @@ object PacketHandler extends CommonPacketHandler { } def onTransposerActivity(p: PacketParser): Unit = - p.readTileEntity[Transposer]() match { + p.readBlockEntity[Transposer]() match { case Some(transposer) => transposer.lastOperation = System.currentTimeMillis() case _ => // Invalid packet. } def onWaypointLabel(p: PacketParser): Unit = - p.readTileEntity[Waypoint]() match { + p.readBlockEntity[Waypoint]() match { case Some(waypoint) => waypoint.label = p.readUTF() case _ => // Invalid packet. } + + protected override def createParser(stream: InputStream, player: PlayerEntity) = new PacketParser(stream, Minecraft.getInstance.player) } diff --git a/src/main/scala/li/cil/oc/client/PacketSender.scala b/src/main/scala/li/cil/oc/client/PacketSender.scala index 90f2351d6b..6e530ddb07 100644 --- a/src/main/scala/li/cil/oc/client/PacketSender.scala +++ b/src/main/scala/li/cil/oc/client/PacketSender.scala @@ -4,28 +4,37 @@ import li.cil.oc.Settings import li.cil.oc.common.CompressedPacketBuilder import li.cil.oc.common.PacketType import li.cil.oc.common.SimplePacketBuilder +import li.cil.oc.common.container import li.cil.oc.common.entity.Drone import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits.Computer import net.minecraft.client.Minecraft -import net.minecraft.client.audio.PositionedSoundRecord -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.init.SoundEvents +import net.minecraft.client.audio.SimpleSound +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.util.SoundEvents import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.ResourceLocation import net.minecraft.util.SoundCategory -import scala.tools.nsc.doc.model.Entity - object PacketSender { // Timestamp after which the next clipboard message may be sent. Used to // avoid spamming large packets on key repeat. protected var clipboardCooldown = 0L - def sendComputerPower(t: Computer, power: Boolean) { + def sendComputerPower(computer: container.Case, power: Boolean) { val pb = new SimplePacketBuilder(PacketType.ComputerPower) - pb.writeTileEntity(t) + pb.writeInt(computer.containerId) + pb.writeBoolean(power) + + pb.sendToServer() + } + + def sendRobotPower(robot: container.Robot, power: Boolean) { + val pb = new SimplePacketBuilder(PacketType.ComputerPower) + + pb.writeInt(robot.containerId) pb.writeBoolean(power) pb.sendToServer() @@ -45,10 +54,10 @@ object PacketSender { pb.sendToServer() } - def sendDronePower(e: Drone, power: Boolean) { + def sendDronePower(drone: container.Drone, power: Boolean) { val pb = new SimplePacketBuilder(PacketType.DronePower) - pb.writeEntity(e) + pb.writeInt(drone.containerId) pb.writeBoolean(power) pb.sendToServer() @@ -74,12 +83,20 @@ object PacketSender { pb.sendToServer() } + def sendTextInput(address: String, codePt: Int) { + val pb = new SimplePacketBuilder(PacketType.TextInput) + + pb.writeUTF(address) + pb.writeInt(codePt) + + pb.sendToServer() + } + def sendClipboard(address: String, value: String) { if (value != null && !value.isEmpty) { if (value.length > 64 * 1024 || System.currentTimeMillis() < clipboardCooldown) { - val player = Minecraft.getMinecraft.player - val handler = Minecraft.getMinecraft.getSoundHandler - handler.playSound(new PositionedSoundRecord(SoundEvents.BLOCK_NOTE_HARP, SoundCategory.MASTER, 1, 1, player.posX.toFloat, player.posY.toFloat, player.posZ.toFloat)) + val handler = Minecraft.getInstance.getSoundManager + handler.play(SimpleSound.forUI(SoundEvents.NOTE_BLOCK_HARP, 1, 1)) } else { clipboardCooldown = System.currentTimeMillis() + value.length / 10 @@ -159,10 +176,10 @@ object PacketSender { pb.sendToServer() } - def sendRackMountableMapping(t: Rack, mountableIndex: Int, nodeIndex: Int, side: Option[EnumFacing]) { + def sendRackMountableMapping(rack: container.Rack, mountableIndex: Int, nodeIndex: Int, side: Option[Direction]) { val pb = new SimplePacketBuilder(PacketType.RackMountableMapping) - pb.writeTileEntity(t) + pb.writeInt(rack.containerId) pb.writeInt(mountableIndex) pb.writeInt(nodeIndex) pb.writeDirection(side) @@ -170,27 +187,27 @@ object PacketSender { pb.sendToServer() } - def sendRackRelayState(t: Rack, enabled: Boolean) { + def sendRackRelayState(rack: container.Rack, enabled: Boolean) { val pb = new SimplePacketBuilder(PacketType.RackRelayState) - pb.writeTileEntity(t) + pb.writeInt(rack.containerId) pb.writeBoolean(enabled) pb.sendToServer() } - def sendRobotAssemblerStart(t: Assembler) { + def sendRobotAssemblerStart(assembler: container.Assembler) { val pb = new SimplePacketBuilder(PacketType.RobotAssemblerStart) - pb.writeTileEntity(t) + pb.writeInt(assembler.containerId) pb.sendToServer() } - def sendRobotStateRequest(dimension: Int, x: Int, y: Int, z: Int) { + def sendRobotStateRequest(dimension: ResourceLocation, x: Int, y: Int, z: Int) { val pb = new SimplePacketBuilder(PacketType.RobotStateRequest) - pb.writeInt(dimension) + pb.writeUTF(dimension.toString) pb.writeInt(x) pb.writeInt(y) pb.writeInt(z) @@ -198,10 +215,10 @@ object PacketSender { pb.sendToServer() } - def sendServerPower(t: Rack, mountableIndex: Int, power: Boolean) { + def sendServerPower(server: container.Server, mountableIndex: Int, power: Boolean) { val pb = new SimplePacketBuilder(PacketType.ServerPower) - pb.writeTileEntity(t) + pb.writeInt(server.containerId) pb.writeInt(mountableIndex) pb.writeBoolean(power) diff --git a/src/main/scala/li/cil/oc/client/Proxy.scala b/src/main/scala/li/cil/oc/client/Proxy.scala index c8a912dbeb..41a4cb75fc 100644 --- a/src/main/scala/li/cil/oc/client/Proxy.scala +++ b/src/main/scala/li/cil/oc/client/Proxy.scala @@ -1,8 +1,11 @@ package li.cil.oc.client +import com.mojang.blaze3d.systems.IRenderCall +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.OpenComputers import li.cil.oc.api import li.cil.oc.client +import li.cil.oc.client.gui.GuiTypes import li.cil.oc.client.renderer.HighlightRenderer import li.cil.oc.client.renderer.MFUTargetRenderer import li.cil.oc.client.renderer.PetRenderer @@ -12,91 +15,91 @@ import li.cil.oc.client.renderer.block.ModelInitialization import li.cil.oc.client.renderer.block.NetSplitterModel import li.cil.oc.client.renderer.entity.DroneRenderer import li.cil.oc.client.renderer.tileentity._ +import li.cil.oc.common +import li.cil.oc.common.{PacketHandler => CommonPacketHandler} +import li.cil.oc.common.{Proxy => CommonProxy} import li.cil.oc.common.component.TextBuffer import li.cil.oc.common.entity.Drone +import li.cil.oc.common.entity.EntityTypes import li.cil.oc.common.event.NanomachinesHandler import li.cil.oc.common.event.RackMountableRenderHandler -import li.cil.oc.common.item.traits.Delegate import li.cil.oc.common.tileentity -import li.cil.oc.common.{Proxy => CommonProxy} import li.cil.oc.util.Audio import net.minecraft.block.Block +import net.minecraft.client.Minecraft +import net.minecraft.client.entity.player.ClientPlayerEntity +import net.minecraft.client.gui.screen.Screen +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item +import net.minecraft.world.World import net.minecraftforge.common.MinecraftForge import net.minecraftforge.fml.client.registry.ClientRegistry import net.minecraftforge.fml.client.registry.RenderingRegistry -import net.minecraftforge.fml.common.event.FMLInitializationEvent -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent -import net.minecraftforge.fml.common.network.NetworkRegistry -import org.lwjgl.opengl.GLContext +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent +import net.minecraftforge.fml.network.NetworkRegistry private[oc] class Proxy extends CommonProxy { - override def preInit(e: FMLPreInitializationEvent) { - super.preInit(e) - - api.API.manual = client.Manual + modBus.register(classOf[GuiTypes]) + modBus.register(ModelInitialization) + modBus.register(NetSplitterModel) + modBus.register(Textures) - CommandHandler.register() + override def preInit() { + super.preInit() - MinecraftForge.EVENT_BUS.register(Textures) - MinecraftForge.EVENT_BUS.register(NetSplitterModel) - - ModelInitialization.preInit() + api.API.manual = client.Manual } - override def init(e: FMLInitializationEvent) { + override def init(e: FMLCommonSetupEvent) { super.init(e) - OpenComputers.channel.register(client.PacketHandler) - - ColorHandler.init() - - RenderingRegistry.registerEntityRenderingHandler(classOf[Drone], DroneRenderer) - - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Adapter], AdapterRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Assembler], AssemblerRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Case], CaseRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Charger], ChargerRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Disassembler], DisassemblerRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.DiskDrive], DiskDriveRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Geolyzer], GeolyzerRenderer) - if (GLContext.getCapabilities.OpenGL15) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Hologram], HologramRenderer) - else - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Hologram], HologramRendererFallback) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Microcontroller], MicrocontrollerRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.NetSplitter], NetSplitterRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.PowerDistributor], PowerDistributorRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Printer], PrinterRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Raid], RaidRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Rack], RackRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Relay], RelayRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.RobotProxy], RobotRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer) - ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Transposer], TransposerRenderer) - - ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste) - - MinecraftForge.EVENT_BUS.register(HighlightRenderer) - MinecraftForge.EVENT_BUS.register(NanomachinesHandler.Client) - MinecraftForge.EVENT_BUS.register(PetRenderer) - MinecraftForge.EVENT_BUS.register(RackMountableRenderHandler) - MinecraftForge.EVENT_BUS.register(Sound) - MinecraftForge.EVENT_BUS.register(TextBuffer) - MinecraftForge.EVENT_BUS.register(MFUTargetRenderer) - MinecraftForge.EVENT_BUS.register(WirelessNetworkDebugRenderer) - - NetworkRegistry.INSTANCE.registerGuiHandler(OpenComputers, GuiHandler) - - MinecraftForge.EVENT_BUS.register(Audio) - MinecraftForge.EVENT_BUS.register(HologramRenderer) - MinecraftForge.EVENT_BUS.register(PetRenderer) - MinecraftForge.EVENT_BUS.register(Sound) - MinecraftForge.EVENT_BUS.register(TextBufferRenderCache) + CommonPacketHandler.clientHandler = PacketHandler + + e.enqueueWork((() => { + ModelInitialization.preInit() + + ColorHandler.init() + + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.DRONE, DroneRenderer) + + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.ADAPTER, AdapterRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.ASSEMBLER, AssemblerRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.CASE, CaseRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.CHARGER, ChargerRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.DISASSEMBLER, DisassemblerRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.DISK_DRIVE, DiskDriveRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.GEOLYZER, GeolyzerRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.HOLOGRAM, HologramRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.MICROCONTROLLER, MicrocontrollerRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.NET_SPLITTER, NetSplitterRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.POWER_DISTRIBUTOR, PowerDistributorRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.PRINTER, PrinterRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.RAID, RaidRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.RACK, RackRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.RELAY, RelayRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.ROBOT, RobotRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.SCREEN, ScreenRenderer) + ClientRegistry.bindTileEntityRenderer(tileentity.TileEntityTypes.TRANSPOSER, TransposerRenderer) + + ClientRegistry.registerKeyBinding(KeyBindings.extendedTooltip) + ClientRegistry.registerKeyBinding(KeyBindings.analyzeCopyAddr) + ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste) + + MinecraftForge.EVENT_BUS.register(HighlightRenderer) + MinecraftForge.EVENT_BUS.register(NanomachinesHandler.Client) + MinecraftForge.EVENT_BUS.register(PetRenderer) + MinecraftForge.EVENT_BUS.register(RackMountableRenderHandler) + MinecraftForge.EVENT_BUS.register(Sound) + MinecraftForge.EVENT_BUS.register(TextBuffer) + MinecraftForge.EVENT_BUS.register(MFUTargetRenderer) + MinecraftForge.EVENT_BUS.register(WirelessNetworkDebugRenderer) + MinecraftForge.EVENT_BUS.register(Audio) + MinecraftForge.EVENT_BUS.register(HologramRenderer) + }): Runnable) + + RenderSystem.recordRenderCall(() => MinecraftForge.EVENT_BUS.register(TextBufferRenderCache)) } - override def registerModel(instance: Delegate, id: String): Unit = ModelInitialization.registerModel(instance, id) - override def registerModel(instance: Item, id: String): Unit = ModelInitialization.registerModel(instance, id) override def registerModel(instance: Block, id: String): Unit = ModelInitialization.registerModel(instance, id) diff --git a/src/main/scala/li/cil/oc/client/Sound.scala b/src/main/scala/li/cil/oc/client/Sound.scala index e578d1cddb..8e123e9ce3 100644 --- a/src/main/scala/li/cil/oc/client/Sound.scala +++ b/src/main/scala/li/cil/oc/client/Sound.scala @@ -12,71 +12,34 @@ import com.google.common.base.Charsets import li.cil.oc.OpenComputers import li.cil.oc.Settings import net.minecraft.client.Minecraft -import net.minecraft.client.audio.SoundManager -import net.minecraft.server.integrated.IntegratedServer +import net.minecraft.client.audio.ITickableSound +import net.minecraft.client.audio.LocatableSound +import net.minecraft.client.audio.SoundEngine import net.minecraft.tileentity.TileEntity import net.minecraft.util.ResourceLocation import net.minecraft.util.SoundCategory -import net.minecraftforge.client.event.sound.SoundLoadEvent +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.event.TickEvent.ClientTickEvent import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.client.FMLClientHandler -import net.minecraftforge.fml.common.FMLCommonHandler -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent -import paulscode.sound.SoundSystemConfig import scala.collection.mutable -import scala.io.Source object Sound { private val sources = mutable.Map.empty[TileEntity, PseudoLoopingStream] private val commandQueue = mutable.PriorityQueue.empty[Command] - private var lastVolume = FMLClientHandler.instance.getClient.gameSettings.getSoundLevel(SoundCategory.BLOCKS) - private val updateTimer = new Timer("OpenComputers-SoundUpdater", true) if (Settings.get.soundVolume > 0) { updateTimer.scheduleAtFixedRate(new TimerTask { override def run() { - sources.synchronized(updateCallable = Some(() => { - updateVolume() - processQueue() - })) + sources.synchronized(Sound.updateCallable = Some(() => processQueue())) } }, 500, 50) } private var updateCallable = None: Option[() => Unit] - // Set in init event. - var manager: SoundManager = _ - - def soundSystem = if (manager != null) manager.sndSystem else null - - private def updateVolume() { - val volume = - if (isGamePaused) 0f - else FMLClientHandler.instance.getClient.gameSettings.getSoundLevel(SoundCategory.BLOCKS) - if (volume != lastVolume) { - lastVolume = volume - sources.synchronized { - for (sound <- sources.values) { - sound.updateVolume() - } - } - } - } - - private def isGamePaused = { - val server = FMLCommonHandler.instance.getMinecraftServerInstance - // Check outside of match to avoid client side class access. - server != null && !server.isDedicatedServer && (server match { - case integrated: IntegratedServer => Minecraft.getMinecraft.isGamePaused - case _ => false - }) - } - private def processQueue() { if (commandQueue.nonEmpty) { commandQueue.synchronized { @@ -113,42 +76,11 @@ object Sound { } } - @SubscribeEvent - def onSoundLoad(event: SoundLoadEvent) { - manager = event.getManager - } - - private var hasPreloaded = Settings.get.soundVolume <= 0 - @SubscribeEvent def onTick(e: ClientTickEvent) { - if (soundSystem != null) { - if (!hasPreloaded) { - hasPreloaded = true - new Thread(new Runnable() { - override def run(): Unit = { - val preloadConfigLocation = new ResourceLocation(Settings.resourceDomain, "sounds/preload.cfg") - val preloadConfigResource = Minecraft.getMinecraft.getResourceManager.getResource(preloadConfigLocation) - for (location <- Source.fromInputStream(preloadConfigResource.getInputStream)(Charsets.UTF_8).getLines()) { - val url = getClass.getClassLoader.getResource(location) - if (url != null) try { - val sourceName = "preload_" + location - soundSystem.newSource(false, sourceName, url, location, true, 0, 0, 0, SoundSystemConfig.ATTENUATION_NONE, 16) - soundSystem.activate(sourceName) - soundSystem.removeSource(sourceName) - } catch { - case _: Throwable => // Meh. - } - else OpenComputers.log.warn(s"Couldn't preload sound $location!") - } - } - }) - } - - sources.synchronized { - updateCallable.foreach(_ ()) - updateCallable = None - } + sources.synchronized { + updateCallable.foreach(_ ()) + updateCallable = None } } @@ -170,7 +102,11 @@ object Sound { private class StartCommand(when: Long, tileEntity: TileEntity, val name: String, val volume: Float) extends Command(when, tileEntity) { override def apply() { sources.synchronized { - sources.getOrElseUpdate(tileEntity, new PseudoLoopingStream(tileEntity, volume)).play(name) + val current = sources.getOrElse(tileEntity, null) + if (current == null || !current.getLocation.getPath.equals(name)) { + if (current != null) current.stop() + sources(tileEntity) = new PseudoLoopingStream(tileEntity, volume, name) + } } } } @@ -203,65 +139,34 @@ object Sound { } } - private class PseudoLoopingStream(val tileEntity: TileEntity, val volume: Float, val source: String = UUID.randomUUID.toString) { - var initialized = false + private class PseudoLoopingStream(val tileEntity: TileEntity, val subVolume: Float, name: String) + extends LocatableSound(new ResourceLocation(OpenComputers.ID, name), SoundCategory.BLOCKS) with ITickableSound { - def updateVolume() { - soundSystem.setVolume(source, lastVolume * volume * Settings.get.soundVolume) - } + var stopped = false + volume = subVolume * Settings.get.soundVolume + relative = tileEntity != null + looping = true + updatePosition() def updatePosition() { - if (tileEntity != null) soundSystem.setPosition(source, tileEntity.getPos.getX, tileEntity.getPos.getY, tileEntity.getPos.getZ) - else soundSystem.setPosition(source, 0, 0, 0) - } - - def play(name: String) { - val resourceName = s"${Settings.resourceDomain}:$name" - val sound = manager.sndHandler.getAccessor(new ResourceLocation(resourceName)) - // Specified return type because apparently this is ambiguous according to Jenkins. I don't even. - val resource = (sound.cloneEntry(): net.minecraft.client.audio.Sound).getSoundAsOggLocation - if (!initialized) { - initialized = true - if (tileEntity != null) soundSystem.newSource(false, source, toUrl(resource), resource.toString, true, tileEntity.getPos.getX, tileEntity.getPos.getY, tileEntity.getPos.getZ, SoundSystemConfig.ATTENUATION_LINEAR, 16) - else soundSystem.newSource(false, source, toUrl(resource), resource.toString, false, 0, 0, 0, SoundSystemConfig.ATTENUATION_NONE, 0) - updateVolume() - soundSystem.activate(source) + if (tileEntity != null) { + val pos = tileEntity.getBlockPos + x = pos.getX + 0.5 + y = pos.getY + 0.5 + z = pos.getZ + 0.5 } - soundSystem.play(source) } - def stop() { - if (soundSystem != null) try { - soundSystem.stop(source) - soundSystem.removeSource(source) - } - catch { - case _: Throwable => - } - } - } + override def canStartSilent() = true - // This is copied from SoundManager.getURLForSoundResource, which is private. - private def toUrl(resource: ResourceLocation): URL = { - val name = s"mcsounddomain:${resource.getResourceDomain}:${resource.getResourcePath}" - try { - new URL(null, name, new URLStreamHandler { - protected def openConnection(url: URL): URLConnection = new URLConnection(url) { - def connect() { - } + override def isStopped() = stopped - override def getInputStream = try { - Minecraft.getMinecraft.getResourceManager.getResource(resource).getInputStream - } catch { - case t: Throwable => - OpenComputers.log.warn(t) - null - } - } - }) - } - catch { - case _: MalformedURLException => null + // Required by ITickableSound, which is required to update position while playing + override def tick() = () + + def stop() { + stopped = true + looping = false } } } diff --git a/src/main/scala/li/cil/oc/client/Textures.scala b/src/main/scala/li/cil/oc/client/Textures.scala index f457d7322a..5eb23ac767 100644 --- a/src/main/scala/li/cil/oc/client/Textures.scala +++ b/src/main/scala/li/cil/oc/client/Textures.scala @@ -1,15 +1,17 @@ package li.cil.oc.client +import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft +import net.minecraft.inventory.container.PlayerContainer +import net.minecraft.client.renderer.texture.SimpleTexture import net.minecraft.client.renderer.texture.TextureAtlasSprite -import net.minecraft.client.renderer.texture.TextureMap import net.minecraft.util.ResourceLocation import net.minecraftforge.client.event.TextureStitchEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent import scala.collection.mutable @@ -19,9 +21,10 @@ object Textures { val Aliased = L("chars_aliased") val AntiAliased = L("chars") - override protected def basePath = "textures/font/%s.png" + override protected def basePath = "font/%s" - override protected def loader(map: TextureMap, loc: ResourceLocation) = Textures.bind(loc) + override protected def loader(e: TextureStitchEvent.Pre, loc: ResourceLocation) = + Minecraft.getInstance.textureManager.register(loc, new SimpleTexture(new ResourceLocation(loc.getNamespace, s"textures/${loc.getPath}.png"))) } object GUI extends TextureBundle { @@ -65,9 +68,10 @@ object Textures { val UpgradeTab = L("upgrade_tab") val Waypoint = L("waypoint") - override protected def basePath = "textures/gui/%s.png" + override protected def basePath = "gui/%s" - override protected def loader(map: TextureMap, loc: ResourceLocation) = Textures.bind(loc) + override protected def loader(e: TextureStitchEvent.Pre, loc: ResourceLocation) = + Minecraft.getInstance.textureManager.register(loc, new SimpleTexture(new ResourceLocation(loc.getNamespace, s"textures/${loc.getPath}.png"))) } object Icons extends TextureBundle { @@ -78,9 +82,10 @@ object Textures { def get(tier: Int) = ForTier.get(tier).orNull - override protected def basePath = "textures/icons/%s.png" + override protected def basePath = "icons/%s" - override protected def loader(map: TextureMap, loc: ResourceLocation) = Textures.bind(loc) + override protected def loader(e: TextureStitchEvent.Pre, loc: ResourceLocation) = + Minecraft.getInstance.textureManager.register(loc, new SimpleTexture(new ResourceLocation(loc.getNamespace, s"textures/${loc.getPath}.png"))) } object Model extends TextureBundle { @@ -91,9 +96,10 @@ object Textures { val Drone = L("drone") val Robot = L("robot") - override protected def basePath = "textures/model/%s.png" + override protected def basePath = "model/%s" - override protected def loader(map: TextureMap, loc: ResourceLocation) = Textures.bind(loc) + override protected def loader(e: TextureStitchEvent.Pre, loc: ResourceLocation) = + Minecraft.getInstance.textureManager.register(loc, new SimpleTexture(new ResourceLocation(loc.getNamespace, s"textures/${loc.getPath}.png"))) } object Item extends TextureBundle { @@ -102,7 +108,7 @@ object Textures { override protected def basePath = "items/%s" - override protected def loader(map: TextureMap, loc: ResourceLocation) = map.registerSprite(loc) + override protected def loader(e: TextureStitchEvent.Pre, loc: ResourceLocation) = e.addSprite(loc) } // These are kept in the block texture atlas to support animations. @@ -118,14 +124,14 @@ object Textures { val ChargerSideOn = L("overlay/charger_side_on") val DisassemblerSideOn = L("overlay/disassembler_side_on") val DisassemblerTopOn = L("overlay/disassembler_top_on") - val DiskDriveFrontActivity = L("overlay/diskDrive_front_activity") + val DiskDriveFrontActivity = L("overlay/diskdrive_front_activity") val GeolyzerTopOn = L("overlay/geolyzer_top_on") val MicrocontrollerFrontLight = L("overlay/microcontroller_front_light") val MicrocontrollerFrontOn = L("overlay/microcontroller_front_on") val MicrocontrollerFrontError = L("overlay/microcontroller_front_error") - val NetSplitterOn = L("overlay/netSplitter_on") - val PowerDistributorSideOn = L("overlay/powerDistributor_side_on") - val PowerDistributorTopOn = L("overlay/powerDistributor_top_on") + val NetSplitterOn = L("overlay/netsplitter_on") + val PowerDistributorSideOn = L("overlay/powerdistributor_side_on") + val PowerDistributorTopOn = L("overlay/powerdistributor_top_on") val RackDiskDrive = L("rack_disk_drive") val RackDiskDriveActivity = L("overlay/rack_disk_drive_activity") val RackServer = L("rack_server") @@ -143,10 +149,10 @@ object Textures { val TransposerOn = L("overlay/transposer_on") val Cable = L("cable") - val CableCap = L("cableCap") + val CableCap = L("cablecap") val GenericTop = L("generic_top", load = false) - val NetSplitterSide = L("netSplitter_side") - val NetSplitterTop = L("netSplitter_top") + val NetSplitterSide = L("netsplitter_side") + val NetSplitterTop = L("netsplitter_top") val RackFront = L("rack_front", load = false) val RackSide = L("rack_side", load = false) @@ -526,61 +532,50 @@ object Textures { Screen.makeSureThisIsInitialized() - def bind(): Unit = Textures.bind(TextureMap.LOCATION_BLOCKS_TEXTURE) + def bind(): Unit = Textures.bind(PlayerContainer.BLOCK_ATLAS) override protected def basePath = "blocks/%s" - override protected def loader(map: TextureMap, loc: ResourceLocation) = map.registerSprite(loc) + override protected def loader(e: TextureStitchEvent.Pre, loc: ResourceLocation) = e.addSprite(loc) } def bind(location: ResourceLocation): Unit = { - if (location == null) RenderState.bindTexture(0) - else { - val manager = Minecraft.getMinecraft.renderEngine - manager.bindTexture(location) - // IMPORTANT: manager.bindTexture uses GlStateManager.bindTexture, and - // that has borked caching, so binding textures will sometimes fail, - // because it'll think the texture is already bound although it isn't. - // So we do it manually. - val texture = manager.getTexture(location) - if (texture != null) { - RenderState.bindTexture(texture.getGlTextureId) - } - } + val texture = if (location != null) Minecraft.getInstance.textureManager.getTexture(location) else null + if (texture != null) texture.bind() + else RenderState.bindTexture(0) } - def getSprite(location: String): TextureAtlasSprite = Minecraft.getMinecraft.getTextureMapBlocks.getAtlasSprite(location) - - def getSprite(location: ResourceLocation): TextureAtlasSprite = getSprite(location.toString) + def getSprite(location: ResourceLocation): TextureAtlasSprite = + Minecraft.getInstance.getModelManager.getAtlas(PlayerContainer.BLOCK_ATLAS).getSprite(location) @SubscribeEvent def onTextureStitchPre(e: TextureStitchEvent.Pre): Unit = { - Font.init(e.getMap) - GUI.init(e.getMap) - Icons.init(e.getMap) - Model.init(e.getMap) - Item.init(e.getMap) - Block.init(e.getMap) + if (e.getMap.location.equals(PlayerContainer.BLOCK_ATLAS)) { + Font.init(e) + GUI.init(e) + Icons.init(e) + Model.init(e) + Item.init(e) + Block.init(e) + } } abstract class TextureBundle { private val locations = mutable.ArrayBuffer.empty[ResourceLocation] - protected def textureManager = Minecraft.getMinecraft.getTextureManager - - final def init(map: TextureMap): Unit = { - locations.foreach(loader(map, _)) + final def init(e: TextureStitchEvent.Pre): Unit = { + locations.foreach(loader(e, _)) } protected def L(name: String, load: Boolean = true) = { - val location = new ResourceLocation(Settings.resourceDomain, String.format(basePath, name)) + val location = new ResourceLocation(OpenComputers.ID, String.format(basePath, name)) if (load) locations += location location } protected def basePath: String - protected def loader(map: TextureMap, loc: ResourceLocation): Unit + protected def loader(e: TextureStitchEvent.Pre, loc: ResourceLocation): Unit } } diff --git a/src/main/scala/li/cil/oc/client/gui/Adapter.scala b/src/main/scala/li/cil/oc/client/gui/Adapter.scala index 1b73504983..475685f0ba 100644 --- a/src/main/scala/li/cil/oc/client/gui/Adapter.scala +++ b/src/main/scala/li/cil/oc/client/gui/Adapter.scala @@ -1,15 +1,9 @@ package li.cil.oc.client.gui -import li.cil.oc.Localization import li.cil.oc.common.container -import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class Adapter(playerInventory: InventoryPlayer, val adapter: tileentity.Adapter) extends DynamicGuiContainer(new container.Adapter(playerInventory, adapter)) { - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(adapter.getName), - 8, 6, 0x404040) - } +class Adapter(state: container.Adapter, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { } diff --git a/src/main/scala/li/cil/oc/client/gui/Assembler.scala b/src/main/scala/li/cil/oc/client/gui/Assembler.scala index 60146d69c2..378a74b038 100644 --- a/src/main/scala/li/cil/oc/client/gui/Assembler.scala +++ b/src/main/scala/li/cil/oc/client/gui/Assembler.scala @@ -1,5 +1,7 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.client.gui.widget.ProgressBar @@ -7,29 +9,29 @@ import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.container import li.cil.oc.common.container.ComponentSlot import li.cil.oc.common.template.AssemblerTemplates -import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.inventory.Slot +import net.minecraft.client.gui.widget.button.Button +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.Slot import net.minecraft.util.text.ITextComponent -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ -class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Assembler) extends DynamicGuiContainer(new container.Assembler(playerInventory, assembler)) { - xSize = 176 - ySize = 192 +class Assembler(state: container.Assembler, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { - for (slot <- inventorySlots.inventorySlots) slot match { + imageWidth = 176 + imageHeight = 192 + + for (slot <- menu.slots) slot match { case component: ComponentSlot => component.changeListener = Option(onSlotChanged) case _ => } private def onSlotChanged(slot: Slot) { - runButton.enabled = canBuild - runButton.toggled = !runButton.enabled + runButton.active = canBuild + runButton.toggled = !runButton.active info = validate } @@ -37,53 +39,57 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse protected var runButton: ImageButton = _ - private val progress = addWidget(new ProgressBar(28, 92)) + private val progress = addCustomWidget(new ProgressBar(28, 92)) - private def validate = AssemblerTemplates.select(inventoryContainer.getSlot(0).getStack).map(_.validate(inventoryContainer.otherInventory)) + private def validate = AssemblerTemplates.select(inventoryContainer.getSlot(0).getItem).map(_.validate(inventoryContainer.otherInventory)) private def canBuild = !inventoryContainer.isAssembling && validate.exists(_._1) - protected override def actionPerformed(button: GuiButton) { - if (button.id == 0 && canBuild) { - ClientPacketSender.sendRobotAssemblerStart(assembler) - } + override protected def init() { + super.init() + runButton = new ImageButton(leftPos + 7, topPos + 89, 18, 18, new Button.IPressable { + override def onPress(b: Button) = if (canBuild) ClientPacketSender.sendRobotAssemblerStart(inventoryContainer) + }, Textures.GUI.ButtonRun, canToggle = true) + addButton(runButton) } - override def initGui() { - super.initGui() - runButton = new ImageButton(0, guiLeft + 7, guiTop + 89, 18, 18, Textures.GUI.ButtonRun, canToggle = true) - add(buttonList, runButton) + override protected def renderLabels(stack: MatrixStack, mouseX: Int, mouseY: Int) { + drawSecondaryForegroundLayer(stack, mouseX, mouseY) + + for (slot <- 0 until menu.slots.size()) { + drawSlotHighlight(stack, menu.getSlot(slot)) + } } - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int): Unit = { + override def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int): Unit = { RenderState.pushAttrib() if (!inventoryContainer.isAssembling) { val message = - if (!inventoryContainer.getSlot(0).getHasStack) { + if (!inventoryContainer.getSlot(0).hasItem) { Localization.Assembler.InsertTemplate } else info match { - case Some((_, value, _)) if value != null => value.getUnformattedText - case _ if inventoryContainer.getSlot(0).getHasStack => Localization.Assembler.CollectResult + case Some((_, value, _)) if value != null => value.getString + case _ if inventoryContainer.getSlot(0).hasItem => Localization.Assembler.CollectResult case _ => "" } - fontRenderer.drawString(message, 30, 94, 0x404040) - if (runButton.isMouseOver) { + font.draw(stack, message, 30, 94, 0x404040) + if (runButton.isMouseOver(mouseX, mouseY)) { val tooltip = new java.util.ArrayList[String] tooltip.add(Localization.Assembler.Run) info.foreach { case (valid, _, warnings) => if (valid && warnings.length > 0) { - tooltip.addAll(warnings.map(_.getUnformattedText).toList) + tooltip.addAll(warnings.map(_.getString).toList) } } - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } } - else if (isPointInRegion(progress.x, progress.y, progress.width, progress.height, mouseX, mouseY)) { + else if (isPointInRegion(progress.x, progress.y, progress.width, progress.height, mouseX - leftPos, mouseY - topPos)) { val tooltip = new java.util.ArrayList[String] val timeRemaining = formatTime(inventoryContainer.assemblyRemainingTime) tooltip.add(Localization.Assembler.Progress(inventoryContainer.assemblyProgress, timeRemaining)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } RenderState.popAttrib() } @@ -94,15 +100,15 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse else f"${seconds / 60}:${seconds % 60}%02d" } - override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1) // Required under Linux. + override protected def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color3f(1, 1, 1) // Required under Linux. Textures.bind(Textures.GUI.RobotAssembler) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) if (inventoryContainer.isAssembling) progress.level = inventoryContainer.assemblyProgress / 100.0 else progress.level = 0 - drawWidgets() - drawInventorySlots() + drawWidgets(stack) + drawInventorySlots(stack) } - override protected def drawDisabledSlot(slot: ComponentSlot) {} + override protected def drawDisabledSlot(stack: MatrixStack, slot: ComponentSlot) {} } diff --git a/src/main/scala/li/cil/oc/client/gui/Case.scala b/src/main/scala/li/cil/oc/client/gui/Case.scala index 7900bce06b..27ab95b807 100644 --- a/src/main/scala/li/cil/oc/client/gui/Case.scala +++ b/src/main/scala/li/cil/oc/client/gui/Case.scala @@ -1,51 +1,48 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.container -import li.cil.oc.common.tileentity -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.client.gui.widget.button.Button +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaCollection +import scala.collection.convert.ImplicitConversionsToJava._ -class Case(playerInventory: InventoryPlayer, val computer: tileentity.Case) extends DynamicGuiContainer(new container.Case(playerInventory, computer)) { - protected var powerButton: ImageButton = _ +class Case(state: container.Case, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { - protected override def actionPerformed(button: GuiButton) { - if (button.id == 0) { - ClientPacketSender.sendComputerPower(computer, !computer.isRunning) - } - } + protected var powerButton: ImageButton = _ - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) { - powerButton.toggled = computer.isRunning - super.drawScreen(mouseX, mouseY, dt) + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float) { + powerButton.toggled = inventoryContainer.isRunning + super.render(stack, mouseX, mouseY, dt) } - override def initGui() { - super.initGui() - powerButton = new ImageButton(0, guiLeft + 70, guiTop + 33, 18, 18, Textures.GUI.ButtonPower, canToggle = true) - add(buttonList, powerButton) + override protected def init() { + super.init() + powerButton = new ImageButton(leftPos + 70, topPos + 33, 18, 18, new Button.IPressable { + override def onPress(b: Button) = ClientPacketSender.sendComputerPower(inventoryContainer, !inventoryContainer.isRunning) + }, Textures.GUI.ButtonPower, canToggle = true) + addButton(powerButton) } - override protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(computer.getName), - 8, 6, 0x404040) - if (powerButton.isMouseOver) { + override protected def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) = { + super.drawSecondaryForegroundLayer(stack, mouseX, mouseY) + if (powerButton.isMouseOver(mouseX, mouseY)) { val tooltip = new java.util.ArrayList[String] - tooltip.addAll(asJavaCollection(if (computer.isRunning) Localization.Computer.TurnOff.lines.toIterable else Localization.Computer.TurnOn.lines.toIterable)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + tooltip.addAll(asJavaCollection(if (inventoryContainer.isRunning) Localization.Computer.TurnOff.lines.toIterable else Localization.Computer.TurnOn.lines.toIterable)) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } } - override def drawSecondaryBackgroundLayer() { - GlStateManager.color(1, 1, 1) + override def drawSecondaryBackgroundLayer(stack: MatrixStack) { + RenderSystem.color3f(1, 1, 1) Textures.bind(Textures.GUI.Computer) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) } } diff --git a/src/main/scala/li/cil/oc/client/gui/Charger.scala b/src/main/scala/li/cil/oc/client/gui/Charger.scala index 1cf35a188f..afb106a42c 100644 --- a/src/main/scala/li/cil/oc/client/gui/Charger.scala +++ b/src/main/scala/li/cil/oc/client/gui/Charger.scala @@ -1,15 +1,9 @@ package li.cil.oc.client.gui -import li.cil.oc.Localization import li.cil.oc.common.container -import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class Charger(playerInventory: InventoryPlayer, val charger: tileentity.Charger) extends DynamicGuiContainer(new container.Charger(playerInventory, charger)) { - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(charger.getName), - 8, 6, 0x404040) - } +class Charger(state: container.Charger, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { } diff --git a/src/main/scala/li/cil/oc/client/gui/CustomGuiContainer.scala b/src/main/scala/li/cil/oc/client/gui/CustomGuiContainer.scala index 9eaf3998f2..aa32642b81 100644 --- a/src/main/scala/li/cil/oc/client/gui/CustomGuiContainer.scala +++ b/src/main/scala/li/cil/oc/client/gui/CustomGuiContainer.scala @@ -2,44 +2,65 @@ package li.cil.oc.client.gui import java.util +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.gui.widget.WidgetContainer import li.cil.oc.util.RenderState import net.minecraft.client.gui.FontRenderer -import net.minecraft.client.gui.inventory.GuiContainer -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.gui.screen.inventory.ContainerScreen +import net.minecraft.client.renderer.IRenderTypeBuffer import net.minecraft.client.renderer.RenderHelper -import net.minecraft.inventory.Container +import net.minecraft.client.renderer.Tessellator +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.Container +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.ITextProperties +import net.minecraft.util.text.LanguageMap +import net.minecraft.util.text.StringTextComponent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ // Workaround because certain other mods *cough*TMI*cough* do base class // transformations that break things! Such fun. Many annoyed. And yes, this // is a common issue, have a look at EnderIO and Enchanting Plus. They have // to work around this, too. -abstract class CustomGuiContainer[C <: Container](val inventoryContainer: C) extends GuiContainer(inventoryContainer) with WidgetContainer { - override def windowX = guiLeft +abstract class CustomGuiContainer[C <: Container](val inventoryContainer: C, inv: PlayerInventory, title: ITextComponent) + extends ContainerScreen(inventoryContainer, inv, title) with WidgetContainer { - override def windowY = guiTop + override def windowX = leftPos - override def windowZ = zLevel + override def windowY = topPos - override def doesGuiPauseGame = false + override def windowZ = getBlitOffset + + override def isPauseScreen = false protected def add[T](list: util.List[T], value: Any) = list.add(value.asInstanceOf[T]) // Pretty much Scalaified copy-pasta from base-class. - override def drawHoveringText(text: util.List[String], x: Int, y: Int, font: FontRenderer): Unit = { - copiedDrawHoveringText(text, x, y, font) + override def renderWrappedToolTip(stack: MatrixStack, text: util.List[_ <: ITextProperties], x: Int, y: Int, font: FontRenderer): Unit = { + copiedDrawHoveringText0(stack, text, x, y, font) } - protected def copiedDrawHoveringText(text: util.List[String], x: Int, y: Int, font: FontRenderer): Unit = { + protected def isPointInRegion(rectX: Int, rectY: Int, rectWidth: Int, rectHeight: Int, pointX: Int, pointY: Int): Boolean = + pointX >= rectX - 1 && pointX < rectX + rectWidth + 1 && pointY >= rectY - 1 && pointY < rectY + rectHeight + 1 + + protected def copiedDrawHoveringText(stack: MatrixStack, lines: util.List[String], x: Int, y: Int, font: FontRenderer): Unit = { + val text = new util.ArrayList[StringTextComponent]() + for (line <- lines) { + text.add(new StringTextComponent(line)) + } + copiedDrawHoveringText0(stack, text, x, y, font) + } + + protected def copiedDrawHoveringText0(stack: MatrixStack, text: util.List[_ <: ITextProperties], x: Int, y: Int, font: FontRenderer): Unit = { if (!text.isEmpty) { - GlStateManager.disableRescaleNormal() - RenderHelper.disableStandardItemLighting() - GlStateManager.disableLighting() - GlStateManager.disableDepth() + RenderSystem.disableRescaleNormal() + RenderHelper.turnOff() + RenderSystem.disableLighting() + RenderSystem.disableDepthTest() - val textWidth = text.map(line => font.getStringWidth(line)).max + val textWidth = text.map(line => font.width(line)).max var posX = x + 12 var posY = y - 12 @@ -54,46 +75,51 @@ abstract class CustomGuiContainer[C <: Container](val inventoryContainer: C) ext posY = height - textHeight - 6 } - zLevel = 300f - itemRender.zLevel = 300f + setBlitOffset(300) + itemRenderer.blitOffset = 300f val bg = 0xF0100010 - drawGradientRect(posX - 3, posY - 4, posX + textWidth + 3, posY - 3, bg, bg) - drawGradientRect(posX - 3, posY + textHeight + 3, posX + textWidth + 3, posY + textHeight + 4, bg, bg) - drawGradientRect(posX - 3, posY - 3, posX + textWidth + 3, posY + textHeight + 3, bg, bg) - drawGradientRect(posX - 4, posY - 3, posX - 3, posY + textHeight + 3, bg, bg) - drawGradientRect(posX + textWidth + 3, posY - 3, posX + textWidth + 4, posY + textHeight + 3, bg, bg) + fillGradient(stack, posX - 3, posY - 4, posX + textWidth + 3, posY - 3, bg, bg) + fillGradient(stack, posX - 3, posY + textHeight + 3, posX + textWidth + 3, posY + textHeight + 4, bg, bg) + fillGradient(stack, posX - 3, posY - 3, posX + textWidth + 3, posY + textHeight + 3, bg, bg) + fillGradient(stack, posX - 4, posY - 3, posX - 3, posY + textHeight + 3, bg, bg) + fillGradient(stack, posX + textWidth + 3, posY - 3, posX + textWidth + 4, posY + textHeight + 3, bg, bg) val color1 = 0x505000FF val color2 = (color1 & 0x00FEFEFE) >> 1 | (color1 & 0xFF000000) - drawGradientRect(posX - 3, posY - 3 + 1, posX - 3 + 1, posY + textHeight + 3 - 1, color1, color2) - drawGradientRect(posX + textWidth + 2, posY - 3 + 1, posX + textWidth + 3, posY + textHeight + 3 - 1, color1, color2) - drawGradientRect(posX - 3, posY - 3, posX + textWidth + 3, posY - 3 + 1, color1, color1) - drawGradientRect(posX - 3, posY + textHeight + 2, posX + textWidth + 3, posY + textHeight + 3, color2, color2) - + fillGradient(stack, posX - 3, posY - 3 + 1, posX - 3 + 1, posY + textHeight + 3 - 1, color1, color2) + fillGradient(stack, posX + textWidth + 2, posY - 3 + 1, posX + textWidth + 3, posY + textHeight + 3 - 1, color1, color2) + fillGradient(stack, posX - 3, posY - 3, posX + textWidth + 3, posY - 3 + 1, color1, color1) + fillGradient(stack, posX - 3, posY + textHeight + 2, posX + textWidth + 3, posY + textHeight + 3, color2, color2) + + stack.pushPose() + stack.translate(0, 0, 400) + val buffer = IRenderTypeBuffer.immediate(Tessellator.getInstance.getBuilder()) for ((line, index) <- text.zipWithIndex) { - font.drawStringWithShadow(line.asInstanceOf[String], posX, posY, -1) + font.drawInBatch(LanguageMap.getInstance.getVisualOrder(line), posX, posY, -1, true, stack.last.pose, buffer, false, 0, 15728880) if (index == 0) { posY += 2 } posY += 10 } - zLevel = 0f - itemRender.zLevel = 0f - - GlStateManager.enableLighting() - GlStateManager.enableDepth() - RenderHelper.enableStandardItemLighting() - GlStateManager.enableRescaleNormal() + buffer.endBatch() + stack.popPose() + setBlitOffset(0) + itemRenderer.blitOffset = 0f + + RenderSystem.enableLighting() + RenderSystem.enableDepthTest() + RenderHelper.turnBackOn() + RenderSystem.enableRescaleNormal() } } - override def drawGradientRect(left: Int, top: Int, right: Int, bottom: Int, startColor: Int, endColor: Int): Unit = { - super.drawGradientRect(left, top, right, bottom, startColor, endColor) + override def fillGradient(stack: MatrixStack, left: Int, top: Int, right: Int, bottom: Int, startColor: Int, endColor: Int): Unit = { + super.fillGradient(stack, left, top, right, bottom, startColor, endColor) RenderState.makeItBlend() } - override def drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float): Unit = { - this.drawDefaultBackground() - super.drawScreen(mouseX, mouseY, partialTicks) - this.renderHoveredToolTip(mouseX, mouseY) + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, partialTicks: Float): Unit = { + this.renderBackground(stack) + super.render(stack, mouseX, mouseY, partialTicks) + this.renderTooltip(stack, mouseX, mouseY) } } diff --git a/src/main/scala/li/cil/oc/client/gui/Database.scala b/src/main/scala/li/cil/oc/client/gui/Database.scala index 36b42f1894..805adf2ab7 100644 --- a/src/main/scala/li/cil/oc/client/gui/Database.scala +++ b/src/main/scala/li/cil/oc/client/gui/Database.scala @@ -1,32 +1,39 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures import li.cil.oc.common.Tier import li.cil.oc.common.container -import li.cil.oc.common.inventory.DatabaseInventory -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class Database(playerInventory: InventoryPlayer, val databaseInventory: DatabaseInventory) extends DynamicGuiContainer(new container.Database(playerInventory, databaseInventory)) with traits.LockedHotbar { - ySize = 256 +class Database(state: container.Database, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) + with traits.LockedHotbar[container.Database] { - override def lockedStack = databaseInventory.container + imageHeight = 256 - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) {} + override def lockedStack = inventoryContainer.container - override protected def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1, 1) + override protected def renderLabels(stack: MatrixStack, mouseX: Int, mouseY: Int) = + drawSecondaryForegroundLayer(stack, mouseX, mouseY) + + override def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) {} + + override protected def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color4f(1, 1, 1, 1) Textures.bind(Textures.GUI.Database) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) - if (databaseInventory.tier > Tier.One) { + if (inventoryContainer.tier > Tier.One) { Textures.bind(Textures.GUI.Database1) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) } - if (databaseInventory.tier > Tier.Two) { + if (inventoryContainer.tier > Tier.Two) { Textures.bind(Textures.GUI.Database2) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) } } } diff --git a/src/main/scala/li/cil/oc/client/gui/Disassembler.scala b/src/main/scala/li/cil/oc/client/gui/Disassembler.scala index 1a90a66b3e..3b8fea9840 100644 --- a/src/main/scala/li/cil/oc/client/gui/Disassembler.scala +++ b/src/main/scala/li/cil/oc/client/gui/Disassembler.scala @@ -1,27 +1,32 @@ package li.cil.oc.client.gui -import li.cil.oc.Localization +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures import li.cil.oc.client.gui.widget.ProgressBar import li.cil.oc.common.container -import li.cil.oc.common.tileentity -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class Disassembler(playerInventory: InventoryPlayer, val disassembler: tileentity.Disassembler) extends DynamicGuiContainer(new container.Disassembler(playerInventory, disassembler)) { - val progress = addWidget(new ProgressBar(18, 65)) +class Disassembler(state: container.Disassembler, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - fontRenderer.drawString( - Localization.localizeImmediately(disassembler.getName), - 8, 6, 0x404040) + val progress = addCustomWidget(new ProgressBar(18, 65)) + + override protected def renderLabels(stack: MatrixStack, mouseX: Int, mouseY: Int) { + font.draw(stack, title, titleLabelX, titleLabelY, 0x404040) + drawSecondaryForegroundLayer(stack, mouseX, mouseY) + + for (slot <- 0 until menu.slots.size()) { + drawSlotHighlight(stack, menu.getSlot(slot)) + } } - override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1) + override def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color3f(1, 1, 1) Textures.bind(Textures.GUI.Disassembler) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) progress.level = inventoryContainer.disassemblyProgress / 100.0 - drawWidgets() + drawWidgets(stack) } } diff --git a/src/main/scala/li/cil/oc/client/gui/DiskDrive.scala b/src/main/scala/li/cil/oc/client/gui/DiskDrive.scala index 14ab5bd7ed..0db7dd3b8e 100644 --- a/src/main/scala/li/cil/oc/client/gui/DiskDrive.scala +++ b/src/main/scala/li/cil/oc/client/gui/DiskDrive.scala @@ -1,15 +1,9 @@ package li.cil.oc.client.gui -import li.cil.oc.Localization import li.cil.oc.common.container -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.inventory.IInventory +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class DiskDrive(playerInventory: InventoryPlayer, val drive: IInventory) extends DynamicGuiContainer(new container.DiskDrive(playerInventory, drive)) { - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(drive.getName), - 8, 6, 0x404040) - } +class DiskDrive(state: container.DiskDrive, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { } diff --git a/src/main/scala/li/cil/oc/client/gui/Drive.scala b/src/main/scala/li/cil/oc/client/gui/Drive.scala index 74185a031e..ab990274ab 100644 --- a/src/main/scala/li/cil/oc/client/gui/Drive.scala +++ b/src/main/scala/li/cil/oc/client/gui/Drive.scala @@ -1,15 +1,18 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.item.data.DriveData -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.gui.GuiScreen -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.client.gui.widget.button.Button +import net.minecraft.client.gui.screen +import net.minecraft.client.settings.KeyBinding +import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemStack +import net.minecraft.util.text.StringTextComponent -class Drive(playerInventory: InventoryPlayer, val driveStack: () => ItemStack) extends GuiScreen with traits.Window { +class Drive(playerInventory: PlayerInventory, val driveStack: () => ItemStack) extends screen.Screen(StringTextComponent.EMPTY) with traits.Window { override val windowHeight = 120 override def backgroundImage = Textures.GUI.Drive @@ -18,46 +21,45 @@ class Drive(playerInventory: InventoryPlayer, val driveStack: () => ItemStack) e protected var unmanagedButton: ImageButton = _ protected var lockedButton: ImageButton = _ - protected override def actionPerformed(button: GuiButton) { - if (button.id == 0) { - ClientPacketSender.sendDriveMode(unmanaged = false) - DriveData.setUnmanaged(driveStack(), unmanaged = false) - } else if (button.id == 1) { - ClientPacketSender.sendDriveMode(unmanaged = true) - DriveData.setUnmanaged(driveStack(), unmanaged = true) - } else if (button.id == 2) { - ClientPacketSender.sendDriveLock() - DriveData.lock(driveStack(), playerInventory.player) - } - updateButtonStates() - } - def updateButtonStates(): Unit = { val data = new DriveData(driveStack()) unmanagedButton.toggled = data.isUnmanaged managedButton.toggled = !unmanagedButton.toggled lockedButton.toggled = data.isLocked - lockedButton.enabled = !data.isLocked + lockedButton.active = !data.isLocked } - override def initGui(): Unit = { - super.initGui() - managedButton = new ImageButton(0, guiLeft + 11, guiTop + 11, 74, 18, Textures.GUI.ButtonDriveMode, text = Localization.Drive.Managed, textColor = 0x608060, canToggle = true) - unmanagedButton = new ImageButton(1, guiLeft + 91, guiTop + 11, 74, 18, Textures.GUI.ButtonDriveMode, text = Localization.Drive.Unmanaged, textColor = 0x608060, canToggle = true) - lockedButton = new ImageButton(2, guiLeft + 11, guiTop + windowHeight - 42, 44, 18, Textures.GUI.ButtonDriveMode, text = Localization.Drive.ReadOnlyLock, textColor = 0x608060, canToggle = true) - add(buttonList, managedButton) - add(buttonList, unmanagedButton) - add(buttonList, lockedButton) + override protected def init(): Unit = { + super.init() + minecraft.mouseHandler.releaseMouse() + KeyBinding.releaseAll() + managedButton = new ImageButton(leftPos + 11, topPos + 11, 74, 18, new Button.IPressable { + override def onPress(b: Button) = { + ClientPacketSender.sendDriveMode(unmanaged = false) + DriveData.setUnmanaged(driveStack(), unmanaged = false) + } + }, Textures.GUI.ButtonDriveMode, text = new StringTextComponent(Localization.Drive.Managed), textColor = 0x608060, canToggle = true) + unmanagedButton = new ImageButton(leftPos + 91, topPos + 11, 74, 18, new Button.IPressable { + override def onPress(b: Button) = { + ClientPacketSender.sendDriveMode(unmanaged = true) + DriveData.setUnmanaged(driveStack(), unmanaged = true) + } + }, Textures.GUI.ButtonDriveMode, text = new StringTextComponent(Localization.Drive.Unmanaged), textColor = 0x608060, canToggle = true) + lockedButton = new ImageButton(leftPos + 11, topPos + windowHeight - 42, 44, 18, new Button.IPressable { + override def onPress(b: Button) = { + ClientPacketSender.sendDriveLock() + DriveData.lock(driveStack(), playerInventory.player) + } + }, Textures.GUI.ButtonDriveMode, text = new StringTextComponent(Localization.Drive.ReadOnlyLock), textColor = 0x608060, canToggle = true) + addButton(managedButton) + addButton(unmanagedButton) + addButton(lockedButton) updateButtonStates() } - override def updateScreen(): Unit = { - super.updateScreen() - } - - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float): Unit = { - super.drawScreen(mouseX, mouseY, dt) - fontRenderer.drawSplitString(Localization.Drive.Warning, guiLeft + 11, guiTop + 37, xSize - 20, 0x404040) - fontRenderer.drawSplitString(Localization.Drive.LockWarning, guiLeft + 61, guiTop + windowHeight - 48, xSize - 68, 0x404040) + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float): Unit = { + super.render(stack, mouseX, mouseY, dt) + font.drawWordWrap(new StringTextComponent(Localization.Drive.Warning), leftPos + 11, topPos + 37, imageWidth - 20, 0x404040) + font.drawWordWrap(new StringTextComponent(Localization.Drive.LockWarning), leftPos + 61, topPos + windowHeight - 48, imageWidth - 68, 0x404040) } } diff --git a/src/main/scala/li/cil/oc/client/gui/Drone.scala b/src/main/scala/li/cil/oc/client/gui/Drone.scala index e144077cc9..da14cfa0c1 100644 --- a/src/main/scala/li/cil/oc/client/gui/Drone.scala +++ b/src/main/scala/li/cil/oc/client/gui/Drone.scala @@ -1,5 +1,7 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.client.gui.widget.ProgressBar @@ -7,22 +9,25 @@ import li.cil.oc.client.renderer.TextBufferRenderCache import li.cil.oc.client.renderer.font.TextBufferRenderData import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.container -import li.cil.oc.common.entity import li.cil.oc.util.PackedColor import li.cil.oc.util.RenderState import li.cil.oc.util.TextBuffer -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.gui.widget.button.Button import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent import org.lwjgl.opengl.GL11 -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaCollection +import scala.collection.convert.ImplicitConversionsToJava._ -class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends DynamicGuiContainer(new container.Drone(playerInventory, drone)) with traits.DisplayBuffer { - xSize = 176 - ySize = 148 +class Drone(state: container.Drone, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) + with traits.DisplayBuffer { + + imageWidth = 176 + imageHeight = 148 protected var powerButton: ImageButton = _ @@ -47,100 +52,97 @@ class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends D private val inventoryX = 97 private val inventoryY = 7 - private val power = addWidget(new ProgressBar(28, 48)) + private val power = addCustomWidget(new ProgressBar(28, 48)) private val selectionSize = 20 private val selectionsStates = 17 - private val selectionStepV = 1 / selectionsStates.toDouble + private val selectionStepV = 1 / selectionsStates.toFloat - protected override def actionPerformed(button: GuiButton) { - if (button.id == 0) { - ClientPacketSender.sendDronePower(drone, !drone.isRunning) - } - } - - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) { - powerButton.toggled = drone.isRunning - bufferRenderer.dirty = drone.statusText.lines.zipWithIndex.exists { + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float) { + powerButton.toggled = inventoryContainer.isRunning + bufferRenderer.dirty = inventoryContainer.statusText.lines.zipWithIndex.exists { case (line, i) => buffer.set(0, i, line, vertical = false) } - super.drawScreen(mouseX, mouseY, dt) + super.render(stack, mouseX, mouseY, dt) } - override def initGui() { - super.initGui() - powerButton = new ImageButton(0, guiLeft + 7, guiTop + 45, 18, 18, Textures.GUI.ButtonPower, canToggle = true) - add(buttonList, powerButton) + override protected def init() { + super.init() + powerButton = new ImageButton(leftPos + 7, topPos + 45, 18, 18, new Button.IPressable { + override def onPress(b: Button) = ClientPacketSender.sendDronePower(inventoryContainer, !inventoryContainer.isRunning) + }, Textures.GUI.ButtonPower, canToggle = true) + addButton(powerButton) } - override protected def drawBuffer() { - GlStateManager.translate(bufferX, bufferY, 0) + override protected def drawBuffer(stack: MatrixStack) { + stack.translate(bufferX, bufferY, 0) RenderState.disableEntityLighting() RenderState.makeItBlend() - GlStateManager.scale(scale, scale, 1) + stack.scale(scale.toFloat, scale.toFloat, 1) RenderState.pushAttrib() - GlStateManager.depthMask(false) - GlStateManager.color(0.5f, 0.5f, 1f) - TextBufferRenderCache.render(bufferRenderer) + RenderSystem.depthMask(false) + RenderSystem.color3f(0.5f, 0.5f, 1f) + TextBufferRenderCache.render(stack, bufferRenderer) RenderState.popAttrib() } - override protected def changeSize(w: Double, h: Double, recompile: Boolean) = 2.0 + override protected def changeSize(w: Double, h: Double) = 2.0 + + override protected def renderLabels(stack: MatrixStack, mouseX: Int, mouseY: Int) = + drawSecondaryForegroundLayer(stack, mouseX, mouseY) - override protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) { - drawBufferLayer() + override protected def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) { + drawBufferLayer(stack) RenderState.pushAttrib() - if (isPointInRegion(power.x, power.y, power.width, power.height, mouseX, mouseY)) { + if (isPointInRegion(power.x, power.y, power.width, power.height, mouseX - leftPos, mouseY - topPos)) { val tooltip = new java.util.ArrayList[String] val format = Localization.Computer.Power + ": %d%% (%d/%d)" tooltip.add(format.format( - drone.globalBuffer * 100 / math.max(drone.globalBufferSize, 1), - drone.globalBuffer, - drone.globalBufferSize)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + inventoryContainer.globalBuffer * 100 / math.max(inventoryContainer.globalBufferSize, 1), + inventoryContainer.globalBuffer, inventoryContainer.globalBufferSize)) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } - if (powerButton.isMouseOver) { + if (powerButton.isMouseOver(mouseX, mouseY)) { val tooltip = new java.util.ArrayList[String] - tooltip.addAll(asJavaCollection(if (drone.isRunning) Localization.Computer.TurnOff.lines.toIterable else Localization.Computer.TurnOn.lines.toIterable)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + tooltip.addAll(asJavaCollection(if (inventoryContainer.isRunning) Localization.Computer.TurnOff.lines.toIterable else Localization.Computer.TurnOn.lines.toIterable)) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } RenderState.popAttrib() } - override protected def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1) + override protected def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color3f(1, 1, 1) Textures.bind(Textures.GUI.Drone) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) - power.level = drone.globalBuffer.toDouble / math.max(drone.globalBufferSize.toDouble, 1.0) - drawWidgets() - if (drone.mainInventory.getSizeInventory > 0) { - drawSelection() + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) + power.level = inventoryContainer.globalBuffer.toFloat / math.max(inventoryContainer.globalBufferSize.toFloat, 1.0f) + drawWidgets(stack) + if (inventoryContainer.otherInventory.getContainerSize > 0) { + drawSelection(stack) } - drawInventorySlots() + drawInventorySlots(stack) } // No custom slots, we just extend DynamicGuiContainer for the highlighting. - override protected def drawSlotBackground(x: Int, y: Int) {} + override protected def drawSlotBackground(stack: MatrixStack, x: Int, y: Int) {} - private def drawSelection() { - val slot = drone.selectedSlot + private def drawSelection(stack: MatrixStack) { + val slot = inventoryContainer.selectedSlot if (slot >= 0 && slot < 16) { - RenderState.makeItBlend() Textures.bind(Textures.GUI.RobotSelection) - val now = System.currentTimeMillis() / 1000.0 - val offsetV = ((now - now.toInt) * selectionsStates).toInt * selectionStepV - val x = guiLeft + inventoryX - 1 + (slot % 4) * (selectionSize - 2) - val y = guiTop + inventoryY - 1 + (slot / 4) * (selectionSize - 2) + val now = System.currentTimeMillis() % 1000 / 1000.0f + val offsetV = (now * selectionsStates).toInt * selectionStepV + val x = leftPos + inventoryX - 1 + (slot % 4) * (selectionSize - 2) + val y = topPos + inventoryY - 1 + (slot / 4) * (selectionSize - 2) val t = Tessellator.getInstance - val r = t.getBuffer + val r = t.getBuilder r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x, y, zLevel).tex(0, offsetV).endVertex() - r.pos(x, y + selectionSize, zLevel).tex(0, offsetV + selectionStepV).endVertex() - r.pos(x + selectionSize, y + selectionSize, zLevel).tex(1, offsetV + selectionStepV).endVertex() - r.pos(x + selectionSize, y, zLevel).tex(1, offsetV).endVertex() - t.draw() + r.vertex(stack.last.pose, x, y, getBlitOffset).uv(0, offsetV).endVertex() + r.vertex(stack.last.pose, x, y + selectionSize, getBlitOffset).uv(0, offsetV + selectionStepV).endVertex() + r.vertex(stack.last.pose, x + selectionSize, y + selectionSize, getBlitOffset).uv(1, offsetV + selectionStepV).endVertex() + r.vertex(stack.last.pose, x + selectionSize, y, getBlitOffset).uv(1, offsetV).endVertex() + t.end() } } } diff --git a/src/main/scala/li/cil/oc/client/gui/DynamicGuiContainer.scala b/src/main/scala/li/cil/oc/client/gui/DynamicGuiContainer.scala index bee3a20419..b78d0ee57f 100644 --- a/src/main/scala/li/cil/oc/client/gui/DynamicGuiContainer.scala +++ b/src/main/scala/li/cil/oc/client/gui/DynamicGuiContainer.scala @@ -1,5 +1,7 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.common @@ -11,134 +13,130 @@ import li.cil.oc.integration.util.ItemSearch import li.cil.oc.util.RenderState import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ -import net.minecraft.client.gui.Gui -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.gui.AbstractGui import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.inventory.Container -import net.minecraft.inventory.Slot -import net.minecraftforge.fml.common.Optional +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.Container +import net.minecraft.inventory.container.Slot +import net.minecraft.util.text.ITextComponent import org.lwjgl.opengl.GL11 -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ -abstract class DynamicGuiContainer[C <: Container](container: C) extends CustomGuiContainer(container) { - protected var hoveredSlot: Option[Slot] = None +abstract class DynamicGuiContainer[C <: Container](container: C, inv: PlayerInventory, title: ITextComponent) + extends CustomGuiContainer(container, inv, title) { protected var hoveredStackNEI: StackOption = EmptyStack - protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) { - fontRenderer.drawString( - Localization.localizeImmediately("container.inventory"), - 8, ySize - 96 + 2, 0x404040) + override protected def init() { + super.init() + // imageHeight is set in the body of the extending class, so it's not available in ours. + inventoryLabelY = imageHeight - 96 + 2 } - override protected def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) { + protected def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) {} + + override protected def renderLabels(stack: MatrixStack, mouseX: Int, mouseY: Int) { + super.renderLabels(stack, mouseX, mouseY) RenderState.pushAttrib() - drawSecondaryForegroundLayer(mouseX, mouseY) + drawSecondaryForegroundLayer(stack, mouseX, mouseY) - for (slot <- 0 until inventorySlots.inventorySlots.size()) { - drawSlotHighlight(inventorySlots.inventorySlots.get(slot)) + for (slot <- 0 until menu.slots.size()) { + drawSlotHighlight(stack, menu.getSlot(slot)) } RenderState.popAttrib() } - protected def drawSecondaryBackgroundLayer() {} + protected def drawSecondaryBackgroundLayer(stack: MatrixStack) {} - override protected def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1, 1) + override protected def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color4f(1, 1, 1, 1) Textures.bind(Textures.GUI.Background) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) - drawSecondaryBackgroundLayer() + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) + drawSecondaryBackgroundLayer(stack) RenderState.makeItBlend() - GlStateManager.disableLighting() + RenderSystem.disableLighting() - drawInventorySlots() + drawInventorySlots(stack) } - protected def drawInventorySlots(): Unit = { - GlStateManager.pushMatrix() - GlStateManager.translate(guiLeft, guiTop, 0) - GlStateManager.disableDepth() - for (slot <- 0 until inventorySlots.inventorySlots.size()) { - drawSlotInventory(inventorySlots.inventorySlots.get(slot)) + protected def drawInventorySlots(stack: MatrixStack): Unit = { + stack.pushPose() + stack.translate(leftPos, topPos, 0) + RenderSystem.disableDepthTest() + for (slot <- 0 until menu.slots.size()) { + drawSlotInventory(stack, menu.getSlot(slot)) } - GlStateManager.enableDepth() - GlStateManager.popMatrix() + RenderSystem.enableDepthTest() + stack.popPose() RenderState.makeItBlend() } - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) { - hoveredSlot = (inventorySlots.inventorySlots collect { - case slot: Slot if isPointInRegion(slot.xPos, slot.yPos, 16, 16, mouseX, mouseY) => slot - }).headOption + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float) { hoveredStackNEI = ItemSearch.hoveredStack(this, mouseX, mouseY) - super.drawScreen(mouseX, mouseY, dt) - - if (Mods.JustEnoughItems.isModAvailable) { - drawJEIHighlights() - } + super.render(stack, mouseX, mouseY, dt) } - protected def drawSlotInventory(slot: Slot) { - GlStateManager.enableBlend() + protected def drawSlotInventory(stack: MatrixStack, slot: Slot) { + RenderSystem.enableBlend() slot match { case component: ComponentSlot if component.slot == common.Slot.None || component.tier == common.Tier.None => - if (!slot.getHasStack && slot.xPos >= 0 && slot.yPos >= 0 && component.tierIcon != null) { - drawDisabledSlot(component) + if (!slot.hasItem && slot.x >= 0 && slot.y >= 0 && component.tierIcon != null) { + drawDisabledSlot(stack, component) } case _ => - zLevel += 1 + setBlitOffset(getBlitOffset + 1) if (!isInPlayerInventory(slot)) { - drawSlotBackground(slot.xPos - 1, slot.yPos - 1) + drawSlotBackground(stack, slot.x - 1, slot.y - 1) } - if (!slot.getHasStack) { + if (!slot.hasItem) { slot match { case component: ComponentSlot => if (component.tierIcon != null) { Textures.bind(component.tierIcon) - Gui.drawModalRectWithCustomSizedTexture(slot.xPos, slot.yPos, 0, 0, 16, 16, 16, 16) + AbstractGui.blit(stack, slot.x, slot.y, getBlitOffset, 0, 0, 16, 16, 16, 16) } if (component.hasBackground) { - Textures.bind(slot.getBackgroundLocation) - Gui.drawModalRectWithCustomSizedTexture(slot.xPos, slot.yPos, 0, 0, 16, 16, 16, 16) + Textures.bind(component.getBackgroundLocation) + AbstractGui.blit(stack, slot.x, slot.y, getBlitOffset, 0, 0, 16, 16, 16, 16) } case _ => } - zLevel -= 1 + setBlitOffset(getBlitOffset - 1) } } - GlStateManager.disableBlend() + RenderSystem.disableBlend() } - protected def drawSlotHighlight(slot: Slot) { - if (mc.player.inventory.getItemStack.isEmpty) slot match { + protected def drawSlotHighlight(matrix: MatrixStack, slot: Slot) { + if (minecraft.player.inventory.getCarried.isEmpty) slot match { case component: ComponentSlot if component.slot == common.Slot.None || component.tier == common.Tier.None => // Ignore. case _ => val currentIsInPlayerInventory = isInPlayerInventory(slot) val drawHighlight = hoveredSlot match { - case Some(hovered) => + case hovered: Slot => val hoveredIsInPlayerInventory = isInPlayerInventory(hovered) (currentIsInPlayerInventory != hoveredIsInPlayerInventory) && - ((currentIsInPlayerInventory && slot.getHasStack && isSelectiveSlot(hovered) && hovered.isItemValid(slot.getStack)) || - (hoveredIsInPlayerInventory && hovered.getHasStack && isSelectiveSlot(slot) && slot.isItemValid(hovered.getStack))) + ((currentIsInPlayerInventory && slot.hasItem && isSelectiveSlot(hovered) && hovered.mayPlace(slot.getItem)) || + (hoveredIsInPlayerInventory && hovered.hasItem && isSelectiveSlot(slot) && slot.mayPlace(hovered.getItem))) case _ => hoveredStackNEI match { - case SomeStack(stack) => !currentIsInPlayerInventory && isSelectiveSlot(slot) && slot.isItemValid(stack) + case SomeStack(stack) => !currentIsInPlayerInventory && isSelectiveSlot(slot) && slot.mayPlace(stack) case _ => false } } if (drawHighlight) { - zLevel += 100 - drawGradientRect( - slot.xPos, slot.yPos, - slot.xPos + 16, slot.yPos + 16, + setBlitOffset(getBlitOffset + 100) + fillGradient(matrix, + slot.x, slot.y, + slot.x + 16, slot.y + 16, 0x80FFFFFF, 0x80FFFFFF) - zLevel -= 100 + setBlitOffset(getBlitOffset - 100) } } } @@ -148,49 +146,27 @@ abstract class DynamicGuiContainer[C <: Container](container: C) extends CustomG case _ => false } - protected def drawDisabledSlot(slot: ComponentSlot) { - GlStateManager.color(1, 1, 1, 1) + protected def drawDisabledSlot(stack: MatrixStack, slot: ComponentSlot) { + RenderSystem.color4f(1, 1, 1, 1) Textures.bind(slot.tierIcon) - Gui.drawModalRectWithCustomSizedTexture(slot.xPos, slot.yPos, 0, 0, 16, 16, 16, 16) + AbstractGui.blit(stack, slot.x, slot.y, getBlitOffset, 0, 0, 16, 16, 16, 16) } - protected def drawSlotBackground(x: Int, y: Int) { - GlStateManager.color(1, 1, 1, 1) + protected def drawSlotBackground(stack: MatrixStack, x: Int, y: Int) { + RenderSystem.color4f(1, 1, 1, 1) Textures.bind(Textures.GUI.Slot) val t = Tessellator.getInstance - val r = t.getBuffer + val r = t.getBuilder r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x, y + 18, zLevel + 1).tex(0, 1).endVertex() - r.pos(x + 18, y + 18, zLevel + 1).tex(1, 1).endVertex() - r.pos(x + 18, y, zLevel + 1).tex(1, 0).endVertex() - r.pos(x, y, zLevel + 1).tex(0, 0).endVertex() - t.draw() + r.vertex(stack.last.pose, x, y + 18, getBlitOffset + 1).uv(0, 1).endVertex() + r.vertex(stack.last.pose, x + 18, y + 18, getBlitOffset + 1).uv(1, 1).endVertex() + r.vertex(stack.last.pose, x + 18, y, getBlitOffset + 1).uv(1, 0).endVertex() + r.vertex(stack.last.pose, x, y, getBlitOffset + 1).uv(0, 0).endVertex() + t.end() } private def isInPlayerInventory(slot: Slot) = container match { - case player: Player => slot.inventory == player.playerInventory + case player: Player => slot.container == player.playerInventory case _ => false } - - override def onGuiClosed(): Unit = { - super.onGuiClosed() - if(Mods.JustEnoughItems.isModAvailable) { - resetJEIHighlights() - } - } - - @Optional.Method(modid = Mods.IDs.JustEnoughItems) - private def drawJEIHighlights(): Unit = { - ModJEI.runtime.foreach { runtime => - val overlay = runtime.getItemListOverlay - hoveredSlot match { - case Some(hovered) if !isInPlayerInventory(hovered) && isSelectiveSlot(hovered) => - overlay.highlightStacks(overlay.getVisibleStacks.filter(hovered.isItemValid)) - case _ => overlay.highlightStacks(List[Nothing]()) - } - } - } - - @Optional.Method(modid = Mods.IDs.JustEnoughItems) - private def resetJEIHighlights() = ModJEI.runtime.foreach(_.getItemListOverlay.highlightStacks(List[Nothing]())) } diff --git a/src/main/scala/li/cil/oc/client/gui/GuiTypes.java b/src/main/scala/li/cil/oc/client/gui/GuiTypes.java new file mode 100644 index 0000000000..f609824e7d --- /dev/null +++ b/src/main/scala/li/cil/oc/client/gui/GuiTypes.java @@ -0,0 +1,38 @@ +package li.cil.oc.client.gui; + +import li.cil.oc.OpenComputers; +import li.cil.oc.common.container.ContainerTypes; +import net.minecraft.client.gui.ScreenManager; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.ContainerType; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; + +public final class GuiTypes { + @SubscribeEvent + public static void clientSetup(FMLClientSetupEvent e) { + // ScreenManager.register is not thread-safe. + e.enqueueWork(() -> { + ScreenManager.register(ContainerTypes.ADAPTER, Adapter::new); + ScreenManager.register(ContainerTypes.ASSEMBLER, Assembler::new); + ScreenManager.register(ContainerTypes.CASE, Case::new); + ScreenManager.register(ContainerTypes.CHARGER, Charger::new); + ScreenManager.register(ContainerTypes.DATABASE, Database::new); + ScreenManager.register(ContainerTypes.DISASSEMBLER, Disassembler::new); + ScreenManager.register(ContainerTypes.DISK_DRIVE, DiskDrive::new); + ScreenManager.register(ContainerTypes.DRONE, Drone::new); + ScreenManager.register(ContainerTypes.PRINTER, Printer::new); + ScreenManager.register(ContainerTypes.RACK, Rack::new); + ScreenManager.register(ContainerTypes.RAID, Raid::new); + ScreenManager.register(ContainerTypes.RELAY, Relay::new); + ScreenManager.register(ContainerTypes.ROBOT, Robot::new); + ScreenManager.register(ContainerTypes.SERVER, Server::new); + ScreenManager.register(ContainerTypes.TABLET, Tablet::new); + }); + } + + private GuiTypes() { + throw new Error(); + } +} diff --git a/src/main/scala/li/cil/oc/client/gui/ImageButton.scala b/src/main/scala/li/cil/oc/client/gui/ImageButton.scala index 837b665b49..7306483be0 100644 --- a/src/main/scala/li/cil/oc/client/gui/ImageButton.scala +++ b/src/main/scala/li/cil/oc/client/gui/ImageButton.scala @@ -1,84 +1,86 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.platform.GlStateManager +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures import net.minecraft.client.Minecraft -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.gui.AbstractGui +import net.minecraft.client.gui.widget.button.Button +import net.minecraft.client.gui.widget.button.Button.IPressable import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats import net.minecraft.util.ResourceLocation -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import org.lwjgl.opengl.GL11 -@SideOnly(Side.CLIENT) -class ImageButton(id: Int, xPos: Int, yPos: Int, w: Int, h: Int, +@OnlyIn(Dist.CLIENT) +class ImageButton(xPos: Int, yPos: Int, w: Int, h: Int, + handler: IPressable, val image: ResourceLocation = null, - text: String = null, + text: ITextComponent = StringTextComponent.EMPTY, val canToggle: Boolean = false, val textColor: Int = 0xE0E0E0, val textDisabledColor: Int = 0xA0A0A0, val textHoverColor: Int = 0xFFFFA0, - val textIndent: Int = -1) extends GuiButton(id, xPos, yPos, w, h, text) { + val textIndent: Int = -1) extends Button(xPos, yPos, w, h, text, handler) { var toggled = false var hoverOverride = false - override def drawButton(mc: Minecraft, mouseX: Int, mouseY: Int, partialTicks: Float) { + override def renderButton(stack: MatrixStack, mouseX: Int, mouseY: Int, partialTicks: Float) { if (visible) { Textures.bind(image) - GlStateManager.color(1, 1, 1, 1) - hovered = mouseX >= x && mouseY >= y && mouseX < x + width && mouseY < y + height + RenderSystem.color4f(1, 1, 1, 1) + isHovered = isMouseOver(mouseX, mouseY) val x0 = x val x1 = x + width val y0 = y val y1 = y + height - val isHovered = hoverOverride || getHoverState(isMouseOver) == 2 + val drawHover = hoverOverride || getYImage(isHovered) == 2 val t = Tessellator.getInstance - val r = t.getBuffer + val r = t.getBuilder if (image != null) { - val u0 = if (toggled) 0.5 else 0 - val u1 = u0 + (if (canToggle) 0.5 else 1) - val v0 = if (hoverOverride || getHoverState(hovered) == 2) 0.5 else 0 - val v1 = v0 + 0.5 + val u0 = if (toggled) 0.5f else 0 + val u1 = u0 + (if (canToggle) 0.5f else 1) + val v0 = if (drawHover) 0.5f else 0 + val v1 = v0 + 0.5f r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x0, y1, zLevel).tex(u0, v1).endVertex() - r.pos(x1, y1, zLevel).tex(u1, v1).endVertex() - r.pos(x1, y0, zLevel).tex(u1, v0).endVertex() - r.pos(x0, y0, zLevel).tex(u0, v0).endVertex() - } - else if (isHovered) { - GlStateManager.color(1, 1, 1, 0.8f) - - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - r.pos(x0, y1, zLevel).endVertex() - r.pos(x1, y1, zLevel).endVertex() - r.pos(x1, y0, zLevel).endVertex() - r.pos(x0, y0, zLevel).endVertex() + r.vertex(stack.last.pose, x0, y1, getBlitOffset).uv(u0, v1).endVertex() + r.vertex(stack.last.pose, x1, y1, getBlitOffset).uv(u1, v1).endVertex() + r.vertex(stack.last.pose, x1, y0, getBlitOffset).uv(u1, v0).endVertex() + r.vertex(stack.last.pose, x0, y0, getBlitOffset).uv(u0, v0).endVertex() + t.end() } else { - GlStateManager.color(1, 1, 1, 0.4f) - - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) - r.pos(x0, y1, zLevel).endVertex() - r.pos(x1, y1, zLevel).endVertex() - r.pos(x1, y0, zLevel).endVertex() - r.pos(x0, y0, zLevel).endVertex() + RenderSystem.enableBlend() + RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA) + val alpha = if (drawHover) 0.8f else 0.4f + r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR) + r.vertex(stack.last.pose, x0, y1, getBlitOffset).color(1, 1, 1, alpha).endVertex() + r.vertex(stack.last.pose, x1, y1, getBlitOffset).color(1, 1, 1, alpha).endVertex() + r.vertex(stack.last.pose, x1, y0, getBlitOffset).color(1, 1, 1, alpha).endVertex() + r.vertex(stack.last.pose, x0, y0, getBlitOffset).color(1, 1, 1, alpha).endVertex() + t.end() + RenderSystem.disableBlend() } - t.draw() - if (displayString != null) { + if (getMessage != StringTextComponent.EMPTY) { val color = - if (!enabled) textDisabledColor - else if (hoverOverride || hovered) textHoverColor + if (!active) textDisabledColor + else if (hoverOverride || isHovered) textHoverColor else textColor - if (textIndent >= 0) drawString(mc.fontRenderer, displayString, textIndent + x, y + (height - 8) / 2, color) - else drawCenteredString(mc.fontRenderer, displayString, x + width / 2, y + (height - 8) / 2, color) + val mc = Minecraft.getInstance + if (textIndent >= 0) AbstractGui.drawString(stack, mc.font, getMessage, textIndent + x, y + (height - 8) / 2, color) + else AbstractGui.drawCenteredString(stack, mc.font, getMessage, x + width / 2, y + (height - 8) / 2, color) } } } diff --git a/src/main/scala/li/cil/oc/client/gui/Manual.scala b/src/main/scala/li/cil/oc/client/gui/Manual.scala index a5f7d6f8d1..cddcef15b8 100644 --- a/src/main/scala/li/cil/oc/client/gui/Manual.scala +++ b/src/main/scala/li/cil/oc/client/gui/Manual.scala @@ -1,5 +1,7 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.api import li.cil.oc.client.Textures @@ -8,15 +10,19 @@ import li.cil.oc.client.renderer.markdown.segment.InteractiveSegment import li.cil.oc.client.renderer.markdown.segment.Segment import li.cil.oc.client.{Manual => ManualAPI} import net.minecraft.client.Minecraft -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.gui.GuiScreen -import net.minecraft.client.renderer.GlStateManager -import org.lwjgl.input.Mouse - -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ - -class Manual extends GuiScreen with traits.Window { +import net.minecraft.client.gui.screen +import net.minecraft.client.gui.widget.button.Button +import net.minecraft.client.util.InputMappings +import net.minecraft.client.settings.KeyBinding +import net.minecraft.util.text.ITextProperties +import net.minecraft.util.text.StringTextComponent +import org.lwjgl.glfw.GLFW + +import scala.collection.JavaConverters.{asJavaIterable, seqAsJavaList} +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ + +class Manual extends screen.Screen(StringTextComponent.EMPTY) with traits.Window { final val documentMaxWidth = 230 final val documentMaxHeight = 176 final val scrollPosX = 244 @@ -34,7 +40,7 @@ class Manual extends GuiScreen with traits.Window { override def backgroundImage = Textures.GUI.Manual - var isDragging = false + var isScrolling = false var document: Segment = null var documentHeight = 0 var currentSegment = None: Option[InteractiveSegment] @@ -58,7 +64,7 @@ class Manual extends GuiScreen with traits.Window { val content = Option(api.Manual.contentFor(ManualAPI.history.top.path)). getOrElse(asJavaIterable(Iterable("Document not found: " + ManualAPI.history.top.path))) document = Document.parse(content) - documentHeight = Document.height(document, documentMaxWidth, fontRenderer) + documentHeight = Document.height(document, documentMaxWidth, font) scrollTo(offset) } @@ -75,122 +81,143 @@ class Manual extends GuiScreen with traits.Window { refreshPage() } else { - Minecraft.getMinecraft.player.closeScreen() - } - } - - override def actionPerformed(button: GuiButton): Unit = { - if (button.id >= 0 && button.id < ManualAPI.tabs.length) { - api.Manual.navigate(ManualAPI.tabs(button.id).path) + onClose() } } - override def initGui(): Unit = { - super.initGui() + override protected def init(): Unit = { + super.init() + minecraft.mouseHandler.releaseMouse() + KeyBinding.releaseAll() for ((tab, i) <- ManualAPI.tabs.zipWithIndex if i < maxTabsPerSide) { - val x = guiLeft + tabPosX - val y = guiTop + tabPosY + i * (tabHeight - 1) - add(buttonList, new ImageButton(i, x, y, tabWidth, tabHeight, Textures.GUI.ManualTab)) + val x = leftPos + tabPosX + val y = topPos + tabPosY + i * (tabHeight - 1) + addButton(new ImageButton(x, y, tabWidth, tabHeight, new Button.IPressable { + override def onPress(b: Button) = api.Manual.navigate(tab.path) + }, Textures.GUI.ManualTab)) } - scrollButton = new ImageButton(-1, guiLeft + scrollPosX, guiTop + scrollPosY, 6, 13, Textures.GUI.ButtonScroll) - add(buttonList, scrollButton) + scrollButton = new ImageButton(leftPos + scrollPosX, topPos + scrollPosY, 6, 13, new Button.IPressable { + override def onPress(b: Button) = () + }, Textures.GUI.ButtonScroll) + addButton(scrollButton) refreshPage() } - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float): Unit = { - super.drawScreen(mouseX, mouseY, dt) + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float): Unit = { + super.render(stack, mouseX, mouseY, dt) - scrollButton.enabled = canScroll - scrollButton.hoverOverride = isDragging + scrollButton.active = canScroll + scrollButton.hoverOverride = isScrolling for ((tab, i) <- ManualAPI.tabs.zipWithIndex if i < maxTabsPerSide) { - val button = buttonList.get(i).asInstanceOf[ImageButton] - GlStateManager.pushMatrix() - GlStateManager.translate(button.x + 5, button.y + 5, zLevel) - tab.renderer.render() - GlStateManager.popMatrix() + val button = buttons.get(i).asInstanceOf[ImageButton] + stack.pushPose() + stack.translate(button.x + 5, button.y + 5, getBlitOffset) + tab.renderer.render(stack) + stack.popPose() } - currentSegment = Document.render(document, guiLeft + 8, guiTop + 8, documentMaxWidth, documentMaxHeight, offset, fontRenderer, mouseX, mouseY) + currentSegment = Document.render(stack, document, leftPos + 8, topPos + 8, documentMaxWidth, documentMaxHeight, offset, font, mouseX, mouseY) + def localizeAndWrap(text: String): java.util.List[_ <: ITextProperties] = { + val lines = Localization.localizeImmediately(text).lines.map(new StringTextComponent(_)) + seqAsJavaList(lines.toSeq) + } - if (!isDragging) currentSegment match { + if (!isScrolling) currentSegment match { case Some(segment) => segment.tooltip match { - case Some(text) if text.nonEmpty => drawHoveringText(seqAsJavaList(Localization.localizeImmediately(text).lines.toSeq), mouseX, mouseY, fontRenderer) + case Some(text) if text.nonEmpty => renderWrappedToolTip(stack, localizeAndWrap(text), mouseX, mouseY, font) case _ => } case _ => } - if (!isDragging) for ((tab, i) <- ManualAPI.tabs.zipWithIndex if i < maxTabsPerSide) { - val button = buttonList.get(i).asInstanceOf[ImageButton] + if (!isScrolling) for ((tab, i) <- ManualAPI.tabs.zipWithIndex if i < maxTabsPerSide) { + val button = buttons.get(i).asInstanceOf[ImageButton] if (mouseX > button.x && mouseX < button.x + tabWidth && mouseY > button.y && mouseY < button.y + tabHeight) tab.tooltip.foreach(text => { - drawHoveringText(seqAsJavaList(Localization.localizeImmediately(text).lines.toSeq), mouseX, mouseY, fontRenderer) + renderWrappedToolTip(stack, localizeAndWrap(text), mouseX, mouseY, font) }) } - if (canScroll && (isCoordinateOverScrollBar(mouseX - guiLeft, mouseY - guiTop) || isDragging)) { - drawHoveringText(seqAsJavaList(Seq(s"${100 * offset / maxOffset}%")), guiLeft + scrollPosX + scrollWidth, scrollButton.y + scrollButton.height + 1, fontRenderer) + if (canScroll && (isCoordinateOverScrollBar(mouseX - leftPos, mouseY - topPos) || isScrolling)) { + val lines = seqAsJavaList(Seq(new StringTextComponent(s"${100 * offset / maxOffset}%"))) + renderWrappedToolTip(stack, lines, leftPos + scrollPosX + scrollWidth, scrollButton.y + scrollButton.getHeight + 1, font) } } - override def keyTyped(char: Char, code: Int): Unit = { - if (code == mc.gameSettings.keyBindJump.getKeyCode) { + override def keyPressed(keyCode: Int, scanCode: Int, mods: Int): Boolean = { + val input = InputMappings.getKey(keyCode, scanCode) + if (minecraft.options.keyJump.isActiveAndMatches(input)) { popPage() + return true } - else if (code == mc.gameSettings.keyBindInventory.getKeyCode) { - mc.player.closeScreen() + if (minecraft.options.keyInventory.isActiveAndMatches(input)) { + onClose() + return true } - else super.keyTyped(char, code) + super.keyPressed(keyCode, scanCode, mods) } - override def handleMouseInput(): Unit = { - super.handleMouseInput() - if (Mouse.hasWheel && Mouse.getEventDWheel != 0) { - if (math.signum(Mouse.getEventDWheel) < 0) scrollDown() - else scrollUp() - } + override def mouseScrolled(mouseX: Double, mouseY: Double, scroll: Double): Boolean = { + if (scroll < 0) scrollDown() + else scrollUp() + true } - override def mouseClicked(mouseX: Int, mouseY: Int, button: Int): Unit = { - super.mouseClicked(mouseX, mouseY, button) - - if (canScroll && button == 0 && isCoordinateOverScrollBar(mouseX - guiLeft, mouseY - guiTop)) { - isDragging = true + override def mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean = { + val (mcx, mcy) = (mouseX.asInstanceOf[Int] - leftPos, mouseY.asInstanceOf[Int] - topPos) + if (canScroll && button == GLFW.GLFW_MOUSE_BUTTON_LEFT && isCoordinateOverScrollBar(mcx, mcy)) { + isScrolling = true scrollMouse(mouseY) + return true } - else if (button == 0) currentSegment.foreach(_.onMouseClick(mouseX, mouseY)) - else if (button == 1) popPage() + if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT && isCoordinateOverContent(mcx, mcy)) { + if (currentSegment.exists(_.onMouseClick(mouseX.asInstanceOf[Int], mouseY.asInstanceOf[Int]))) { + return true + } + } + if (button == GLFW.GLFW_MOUSE_BUTTON_RIGHT) { + popPage() + return true + } + super.mouseClicked(mouseX, mouseY, button) } - override protected def mouseClickMove(mouseX: Int, mouseY: Int, lastButtonClicked: Int, timeSinceMouseClick: Long) { - super.mouseClickMove(mouseX, mouseY, lastButtonClicked, timeSinceMouseClick) - if (isDragging) { + override def mouseMoved(mouseX: Double, mouseY: Double): Unit = { + if (isScrolling) scrollMouse(mouseY) + super.mouseMoved(mouseX, mouseY) + } + + override def mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean = { + if (isScrolling) { scrollMouse(mouseY) + return true } + super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY) } - override protected def mouseReleased(mouseX: Int, mouseY: Int, button: Int) { - super.mouseReleased(mouseX, mouseY, button) - if (button == 0) { - isDragging = false + override def mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean = { + if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT && isScrolling) { + isScrolling = false + return true } + super.mouseReleased(mouseX, mouseY, button) } - private def scrollMouse(mouseY: Int) { - scrollTo(math.round((mouseY - guiTop - scrollPosY - 6.5) * maxOffset / (scrollHeight - 13.0)).toInt) + private def scrollMouse(mouseY: Double) { + scrollTo(math.round((mouseY - topPos - scrollPosY - 6.5) * maxOffset / (scrollHeight - 13.0)).toInt) } - private def scrollUp() = scrollTo(offset - Document.lineHeight(fontRenderer) * 3) + private def scrollUp() = scrollTo(offset - Document.lineHeight(font) * 3) - private def scrollDown() = scrollTo(offset + Document.lineHeight(fontRenderer) * 3) + private def scrollDown() = scrollTo(offset + Document.lineHeight(font) * 3) private def scrollTo(row: Int): Unit = { ManualAPI.history.top.offset = math.max(0, math.min(maxOffset, row)) - val yMin = guiTop + scrollPosY + val yMin = topPos + scrollPosY if (maxOffset > 0) { scrollButton.y = yMin + (scrollHeight - 13) * offset / maxOffset } @@ -199,7 +226,11 @@ class Manual extends GuiScreen with traits.Window { } } + private def isCoordinateOverContent(x: Int, y: Int) = + x >= 8 && x < 8 + documentMaxWidth && + y >= 8 && y < 8 + documentMaxHeight + private def isCoordinateOverScrollBar(x: Int, y: Int) = - x > scrollPosX && x < scrollPosX + scrollWidth && + x >= scrollPosX && x < scrollPosX + scrollWidth && y >= scrollPosY && y < scrollPosY + scrollHeight } diff --git a/src/main/scala/li/cil/oc/client/gui/Printer.scala b/src/main/scala/li/cil/oc/client/gui/Printer.scala index 41a96f69e9..ce20911a96 100644 --- a/src/main/scala/li/cil/oc/client/gui/Printer.scala +++ b/src/main/scala/li/cil/oc/client/gui/Printer.scala @@ -1,34 +1,36 @@ package li.cil.oc.client.gui -import li.cil.oc.Localization +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures import li.cil.oc.client.gui.widget.ProgressBar import li.cil.oc.common.container import li.cil.oc.common.container.ComponentSlot -import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) extends DynamicGuiContainer(new container.Printer(playerInventory, printer)) { - xSize = 176 - ySize = 166 +class Printer(state: container.Printer, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { - private val materialBar = addWidget(new ProgressBar(40, 21) { + imageWidth = 176 + imageHeight = 166 + + private val materialBar = addCustomWidget(new ProgressBar(40, 21) { override def width = 62 override def height = 12 override def barTexture = Textures.GUI.PrinterMaterial }) - private val inkBar = addWidget(new ProgressBar(40, 53) { + private val inkBar = addCustomWidget(new ProgressBar(40, 53) { override def width = 62 override def height = 12 override def barTexture = Textures.GUI.PrinterInk }) - private val progressBar = addWidget(new ProgressBar(105, 20) { + private val progressBar = addCustomWidget(new ProgressBar(105, 20) { override def width = 46 override def height = 46 @@ -36,39 +38,32 @@ class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) override def barTexture = Textures.GUI.PrinterProgress }) - override def initGui() { - super.initGui() - } - - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(printer.getName), - 8, 6, 0x404040) + override def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) = { + super.drawSecondaryForegroundLayer(stack, mouseX, mouseY) RenderState.pushAttrib() - if (isPointInRegion(materialBar.x, materialBar.y, materialBar.width, materialBar.height, mouseX, mouseY)) { + if (isPointInRegion(materialBar.x, materialBar.y, materialBar.width, materialBar.height, mouseX - leftPos, mouseY - topPos)) { val tooltip = new java.util.ArrayList[String] - tooltip.add(inventoryContainer.amountMaterial + "/" + printer.maxAmountMaterial) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + tooltip.add(inventoryContainer.amountMaterial + "/" + inventoryContainer.maxAmountMaterial) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } - if (isPointInRegion(inkBar.x, inkBar.y, inkBar.width, inkBar.height, mouseX, mouseY)) { + if (isPointInRegion(inkBar.x, inkBar.y, inkBar.width, inkBar.height, mouseX - leftPos, mouseY - topPos)) { val tooltip = new java.util.ArrayList[String] - tooltip.add(inventoryContainer.amountInk + "/" + printer.maxAmountInk) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + tooltip.add(inventoryContainer.amountInk + "/" + inventoryContainer.maxAmountInk) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } RenderState.popAttrib() } - override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1) + override def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color3f(1, 1, 1) Textures.bind(Textures.GUI.Printer) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) - materialBar.level = inventoryContainer.amountMaterial / printer.maxAmountMaterial.toDouble - inkBar.level = inventoryContainer.amountInk / printer.maxAmountInk.toDouble + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) + materialBar.level = inventoryContainer.amountMaterial / inventoryContainer.maxAmountMaterial.toDouble + inkBar.level = inventoryContainer.amountInk / inventoryContainer.maxAmountInk.toDouble progressBar.level = inventoryContainer.progress - drawWidgets() - drawInventorySlots() + drawWidgets(stack) + drawInventorySlots(stack) } - override protected def drawDisabledSlot(slot: ComponentSlot) {} + override protected def drawDisabledSlot(stack: MatrixStack, slot: ComponentSlot) {} } diff --git a/src/main/scala/li/cil/oc/client/gui/Rack.scala b/src/main/scala/li/cil/oc/client/gui/Rack.scala index 8929fe3ac2..c2bac7f5b6 100644 --- a/src/main/scala/li/cil/oc/client/gui/Rack.scala +++ b/src/main/scala/li/cil/oc/client/gui/Rack.scala @@ -1,23 +1,27 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.container -import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.gui.widget.button.Button import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.util.EnumFacing +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.Direction +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import org.lwjgl.opengl.GL11 -import scala.collection.convert.WrapAsJava.asJavaCollection +import scala.collection.JavaConverters.asJavaCollection -class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends DynamicGuiContainer(new container.Rack(playerInventory, rack)) { - ySize = 210 +class Rack(state: container.Rack, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { + + imageHeight = 210 final val busMasterBlankUVs = (195, 14, 3, 5) final val busMasterPresentUVs = (194, 20, 5, 5) @@ -73,109 +77,94 @@ class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends (83, 104) ) - final val busToSide = EnumFacing.values().filter(_ != EnumFacing.SOUTH) + final val busToSide = Direction.values().filter(_ != Direction.SOUTH) final val sideToBus = busToSide.zipWithIndex.toMap var relayButton: ImageButton = _ // bus -> mountable -> connectable - var wireButtons = Array.fill(rack.getSizeInventory)(Array.fill(4)(Array.fill(5)(null: ImageButton))) - - def sideName(side: EnumFacing) = side match { - case EnumFacing.UP => Localization.Rack.Top - case EnumFacing.DOWN => Localization.Rack.Bottom - case EnumFacing.EAST => Localization.Rack.Left - case EnumFacing.WEST => Localization.Rack.Right - case EnumFacing.NORTH => Localization.Rack.Back + var wireButtons = Array.fill(inventoryContainer.otherInventory.getContainerSize)(Array.fill(4)(Array.fill(5)(null: ImageButton))) + + def sideName(side: Direction) = side match { + case Direction.UP => Localization.Rack.Top + case Direction.DOWN => Localization.Rack.Bottom + case Direction.EAST => Localization.Rack.Left + case Direction.WEST => Localization.Rack.Right + case Direction.NORTH => Localization.Rack.Back case _ => Localization.Rack.None } - def encodeButtonId(mountable: Int, connectable: Int, bus: Int) = { - // +1 to offset for relay button - 1 + mountable * 4 * 5 + connectable * 5 + bus - } - - def decodeButtonId(buttonId: Int) = { - // -1 to offset for relay button - val bus = (buttonId - 1) % 5 - val connectable = ((buttonId - 1) / 5) % 4 - val mountable = (buttonId - 1) / 5 / 4 - (mountable, connectable, bus) - } - - protected override def actionPerformed(button: GuiButton) { - if (button.id == 0) { - ClientPacketSender.sendRackRelayState(rack, !rack.isRelayEnabled) + protected def onRackButton(mountable: Int, connectable: Int, bus: Int) { + if (inventoryContainer.nodeMapping(mountable)(connectable).contains(busToSide(bus))) { + ClientPacketSender.sendRackMountableMapping(inventoryContainer, mountable, connectable, None) } else { - val (mountable, connectable, bus) = decodeButtonId(button.id) - if (rack.nodeMapping(mountable)(connectable).contains(busToSide(bus))) { - ClientPacketSender.sendRackMountableMapping(rack, mountable, connectable, None) - } - else { - ClientPacketSender.sendRackMountableMapping(rack, mountable, connectable, Option(busToSide(bus))) - } + ClientPacketSender.sendRackMountableMapping(inventoryContainer, mountable, connectable, Option(busToSide(bus))) } } - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) { + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float) { for (bus <- 0 until 5) { - for (mountable <- 0 until rack.getSizeInventory) { + for (mountable <- 0 until inventoryContainer.otherInventory.getContainerSize) { val presence = inventoryContainer.nodePresence(mountable) for (connectable <- 0 until 4) { wireButtons(mountable)(connectable)(bus).visible = presence(connectable) } } } - relayButton.displayString = if (rack.isRelayEnabled) Localization.Rack.RelayEnabled else Localization.Rack.RelayDisabled - super.drawScreen(mouseX, mouseY, dt) + val relayMessage = if (inventoryContainer.isRelayEnabled) Localization.Rack.RelayEnabled else Localization.Rack.RelayDisabled + relayButton.setMessage(new StringTextComponent(relayMessage)) + super.render(stack, mouseX, mouseY, dt) } - override def initGui() { - super.initGui() + override protected def init() { + super.init() - relayButton = new ImageButton(0, guiLeft + 101, guiTop + 96, 65, 18, Textures.GUI.ButtonRelay, Localization.Rack.RelayDisabled, textIndent = 18) - add(buttonList, relayButton) + relayButton = new ImageButton(leftPos + 101, topPos + 96, 65, 18, new Button.IPressable { + override def onPress(b: Button) = ClientPacketSender.sendRackRelayState(inventoryContainer, !inventoryContainer.isRelayEnabled) + }, Textures.GUI.ButtonRelay, new StringTextComponent(Localization.Rack.RelayDisabled), textIndent = 18) + addButton(relayButton) val (mw, mh) = hoverMasterSize val (sw, sh) = hoverSlaveSize val (_, _, _, mbh) = busMasterBlankUVs val (_, _, _, sbh) = busSlaveBlankUVs for (bus <- 0 until 5) { - for (mountable <- 0 until rack.getSizeInventory) { + for (mountable <- 0 until inventoryContainer.otherInventory.getContainerSize) { val offset = mountable * (mbh + sbh * 3 + busGap) val (bx, by) = busStart(bus) { - val button = new ImageButton(encodeButtonId(mountable, 0, bus), guiLeft + bx, guiTop + by + offset + 1, mw, mh) - add(buttonList, button) + val button = new ImageButton(leftPos + bx, topPos + by + offset + 1, mw, mh, new Button.IPressable { + override def onPress(b: Button) = onRackButton(mountable, 0, bus) + }) + addButton(button) wireButtons(mountable)(0)(bus) = button } for (connectable <- 0 until 3) { - val button = new ImageButton(encodeButtonId(mountable, connectable + 1, bus), guiLeft + bx, guiTop + by + offset + 1 + mbh + sbh * connectable, sw, sh) - add(buttonList, button) + val button = new ImageButton(leftPos + bx, topPos + by + offset + 1 + mbh + sbh * connectable, sw, sh, new Button.IPressable { + override def onPress(b: Button) = onRackButton(mountable, connectable + 1, bus) + }) + addButton(button) wireButtons(mountable)(connectable + 1)(bus) = button } } } } - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) + override def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) = { + super.drawSecondaryForegroundLayer(stack, mouseX, mouseY) RenderState.pushAttrib() // Prevents NEI render glitch. - fontRenderer.drawString( - Localization.localizeImmediately(rack.getName), - 8, 6, 0x404040) - - GlStateManager.color(1, 1, 1) - mc.renderEngine.bindTexture(Textures.GUI.Rack) + RenderSystem.color4f(1, 1, 1, 1) + RenderState.makeItBlend() + minecraft.getTextureManager.bind(Textures.GUI.Rack) - if (rack.isRelayEnabled) { + if (inventoryContainer.isRelayEnabled) { val (left, top, w, h) = relayModeUVs for ((x, y) <- wireRelay) { - drawRect(x, y, w, h, left, top) + drawRect(stack, x, y, w, h, left, top) } } @@ -185,32 +174,32 @@ class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends val (scx, scy, scw, sch) = connectorSlaveUVs val (sbx, sby, sbw, sbh) = busSlaveBlankUVs val (spx, spy, spw, sph) = busSlavePresentUVs - for (mountable <- 0 until rack.getSizeInventory) { + for (mountable <- 0 until inventoryContainer.otherInventory.getContainerSize) { val presence = inventoryContainer.nodePresence(mountable) // Draw connectable indicators next to item slots. val (cx, cy) = connectorStart(mountable) if (presence(0)) { - drawRect(cx, cy, mcw, mch, mcx, mcy) - rack.nodeMapping(mountable)(0) match { + drawRect(stack, cx, cy, mcw, mch, mcx, mcy) + inventoryContainer.nodeMapping(mountable)(0) match { case Some(side) => val bus = sideToBus(side) val (mwx, mwy, mww, mwh) = wireMasterUVs(bus) for (i <- 0 to bus) { val xOffset = mcw + i * (mpw + mww) - drawRect(cx + xOffset, cy, mww, mwh, mwx, mwy) + drawRect(stack, cx + xOffset, cy, mww, mwh, mwx, mwy) } case _ => } for (connectable <- 1 until 4) { - rack.nodeMapping(mountable)(connectable) match { + inventoryContainer.nodeMapping(mountable)(connectable) match { case Some(side) => val bus = sideToBus(side) val (swx, swy, sww, swh) = wireSlaveUVs(bus) val yOffset = (mch + connectorGap) + (sch + connectorGap) * (connectable - 1) for (i <- 0 to bus) { val xOffset = scw + i * (spw + sww) - drawRect(cx + xOffset, cy + yOffset, sww, swh, swx, swy) + drawRect(stack, cx + xOffset, cy + yOffset, sww, swh, swx, swy) } case _ => } @@ -219,7 +208,7 @@ class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends for (connectable <- 1 until 4) { if (presence(connectable)) { val yOffset = (mch + connectorGap) + (sch + connectorGap) * (connectable - 1) - drawRect(cx, cy + yOffset, scw, sch, scx, scy) + drawRect(stack, cx, cy + yOffset, scw, sch, scx, scy) } } @@ -228,17 +217,17 @@ class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends for (bus <- 0 until 5) { val (bx, by) = busStart(bus) if (presence(0)) { - drawRect(bx - 1, by + yOffset, mpw, mph, mpx, mpy) + drawRect(stack, bx - 1, by + yOffset, mpw, mph, mpx, mpy) } else { - drawRect(bx, by + yOffset, mbw, mbh, mbx, mby) + drawRect(stack, bx, by + yOffset, mbw, mbh, mbx, mby) } for (connectable <- 0 until 3) { if (presence(connectable + 1)) { - drawRect(bx - 1, by + yOffset + mph + sph * connectable, spw, sph, spx, spy) + drawRect(stack, bx - 1, by + yOffset + mph + sph * connectable, spw, sph, spx, spy) } else { - drawRect(bx, by + yOffset + mbh + sbh * connectable, sbw, sbh, sbx, sby) + drawRect(stack, bx, by + yOffset + mbh + sbh * connectable, sbw, sbh, sbx, sby) } } } @@ -248,38 +237,38 @@ class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends val x = 122 val y = 20 + bus * 11 - fontRenderer.drawString( + font.draw(stack, Localization.localizeImmediately(sideName(busToSide(bus))), x, y, 0x404040) } - if (relayButton.isMouseOver) { + if (relayButton.isMouseOver(mouseX, mouseY)) { val tooltip = new java.util.ArrayList[String] tooltip.addAll(asJavaCollection(Localization.Rack.RelayModeTooltip.lines.toIterable)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } RenderState.popAttrib() } - override def drawSecondaryBackgroundLayer() { - GlStateManager.color(1, 1, 1) // Required under Linux. - mc.renderEngine.bindTexture(Textures.GUI.Rack) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + override def drawSecondaryBackgroundLayer(stack: MatrixStack) { + RenderSystem.color3f(1, 1, 1) // Required under Linux. + minecraft.getTextureManager.bind(Textures.GUI.Rack) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) } - private def drawRect(x: Int, y: Int, w: Int, h: Int, u: Int, v: Int): Unit = { + private def drawRect(stack: MatrixStack, x: Int, y: Int, w: Int, h: Int, u: Int, v: Int): Unit = { val u0 = u / 256f val v0 = v / 256f val u1 = u0 + w / 256f val v1 = v0 + h / 256f val t = Tessellator.getInstance() - val r = t.getBuffer + val r = t.getBuilder r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x, y, windowZ).tex(u0, v0).endVertex() - r.pos(x, y + h, windowZ).tex(u0, v1).endVertex() - r.pos(x + w, y + h, windowZ).tex(u1, v1).endVertex() - r.pos(x + w, y, windowZ).tex(u1, v0).endVertex() - t.draw() + r.vertex(stack.last.pose, x, y, windowZ).uv(u0, v0).endVertex() + r.vertex(stack.last.pose, x, y + h, windowZ).uv(u0, v1).endVertex() + r.vertex(stack.last.pose, x + w, y + h, windowZ).uv(u1, v1).endVertex() + r.vertex(stack.last.pose, x + w, y, windowZ).uv(u1, v0).endVertex() + t.end() } } diff --git a/src/main/scala/li/cil/oc/client/gui/Raid.scala b/src/main/scala/li/cil/oc/client/gui/Raid.scala index 56e75f707e..ffd2ba6706 100644 --- a/src/main/scala/li/cil/oc/client/gui/Raid.scala +++ b/src/main/scala/li/cil/oc/client/gui/Raid.scala @@ -1,27 +1,18 @@ package li.cil.oc.client.gui -import li.cil.oc.Localization +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures import li.cil.oc.common.container -import li.cil.oc.common.tileentity -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class Raid(playerInventory: InventoryPlayer, val raid: tileentity.Raid) extends DynamicGuiContainer(new container.Raid(playerInventory, raid)) { - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(raid.getName), - 8, 6, 0x404040) +class Raid(state: container.Raid, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { - fontRenderer.drawSplitString( - Localization.Raid.Warning, - 8, 46, 0x404040, width - 16) - } - - override def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1) // Required under Linux. + override def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color3f(1, 1, 1) // Required under Linux. Textures.bind(Textures.GUI.Raid) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) } } diff --git a/src/main/scala/li/cil/oc/client/gui/Relay.scala b/src/main/scala/li/cil/oc/client/gui/Relay.scala index fcbe9d50a4..93684d6fb7 100644 --- a/src/main/scala/li/cil/oc/client/gui/Relay.scala +++ b/src/main/scala/li/cil/oc/client/gui/Relay.scala @@ -2,90 +2,90 @@ package li.cil.oc.client.gui import java.text.DecimalFormat +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.common.container -import li.cil.oc.common.tileentity import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager import net.minecraft.client.renderer.Tessellator +import net.minecraft.client.renderer.Rectangle2d import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent import org.lwjgl.opengl.GL11 -import org.lwjgl.util.Rectangle -class Relay(playerInventory: InventoryPlayer, val relay: tileentity.Relay) extends DynamicGuiContainer(new container.Relay(playerInventory, relay)) { +class Relay(state: container.Relay, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) { + private val format = new DecimalFormat("#.##hz") - val tabPosition = new Rectangle(xSize, 10, 23, 26) + val tabPosition = new Rectangle2d(imageWidth, 10, 23, 26) - override protected def drawSecondaryBackgroundLayer(): Unit = { - super.drawSecondaryBackgroundLayer() + override protected def drawSecondaryBackgroundLayer(stack: MatrixStack): Unit = { + super.drawSecondaryBackgroundLayer(stack) // Tab background. - GlStateManager.color(1, 1, 1, 1) - Minecraft.getMinecraft.getTextureManager.bindTexture(Textures.GUI.UpgradeTab) + RenderSystem.color4f(1, 1, 1, 1) + Minecraft.getInstance.getTextureManager.bind(Textures.GUI.UpgradeTab) val x = windowX + tabPosition.getX val y = windowY + tabPosition.getY val w = tabPosition.getWidth val h = tabPosition.getHeight val t = Tessellator.getInstance - val r = t.getBuffer + val r = t.getBuilder r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x, y + h, zLevel).tex(0, 1).endVertex() - r.pos(x + w, y + h, zLevel).tex(1, 1).endVertex() - r.pos(x + w, y, zLevel).tex(1, 0).endVertex() - r.pos(x, y, zLevel).tex(0, 0).endVertex() - t.draw() + r.vertex(stack.last.pose, x, y + h, getBlitOffset).uv(0, 1).endVertex() + r.vertex(stack.last.pose, x + w, y + h, getBlitOffset).uv(1, 1).endVertex() + r.vertex(stack.last.pose, x + w, y, getBlitOffset).uv(1, 0).endVertex() + r.vertex(stack.last.pose, x, y, getBlitOffset).uv(0, 0).endVertex() + t.end() } - override def mouseClicked(mouseX: Int, mouseY: Int, button: Int): Unit = { + override def mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean = { // So MC doesn't throw away the item in the upgrade slot when we're trying to pick it up... - val originalWidth = xSize + val originalWidth = imageWidth try { - xSize += tabPosition.getWidth + imageWidth += tabPosition.getWidth super.mouseClicked(mouseX, mouseY, button) } finally { - xSize = originalWidth + imageWidth = originalWidth } } - override def mouseReleased(mouseX: Int, mouseY: Int, button: Int): Unit = { + override def mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean = { // So MC doesn't throw away the item in the upgrade slot when we're trying to pick it up... - val originalWidth = xSize + val originalWidth = imageWidth try { - xSize += tabPosition.getWidth + imageWidth += tabPosition.getWidth super.mouseReleased(mouseX, mouseY, button) } finally { - xSize = originalWidth + imageWidth = originalWidth } } - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int): Unit = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(relay.getName), - 8, 6, 0x404040) + override def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int): Unit = { + super.drawSecondaryForegroundLayer(stack, mouseX, mouseY) - fontRenderer.drawString( + font.draw(stack, Localization.Switch.TransferRate, 14, 20, 0x404040) - fontRenderer.drawString( + font.draw(stack, Localization.Switch.PacketsPerCycle, 14, 39, 0x404040) - fontRenderer.drawString( + font.draw(stack, Localization.Switch.QueueSize, 14, 58, 0x404040) - fontRenderer.drawString( + font.draw(stack, format.format(20f / inventoryContainer.relayDelay), 108, 20, 0x404040) - fontRenderer.drawString( + font.draw(stack, inventoryContainer.packetsPerCycleAvg + " / " + inventoryContainer.relayAmount, 108, 39, thresholdBasedColor(inventoryContainer.packetsPerCycleAvg, math.ceil(inventoryContainer.relayAmount / 2f).toInt, inventoryContainer.relayAmount)) - fontRenderer.drawString( + font.draw(stack, inventoryContainer.queueSize + " / " + inventoryContainer.maxQueueSize, 108, 58, thresholdBasedColor(inventoryContainer.queueSize, inventoryContainer.maxQueueSize / 2, inventoryContainer.maxQueueSize)) } diff --git a/src/main/scala/li/cil/oc/client/gui/Robot.scala b/src/main/scala/li/cil/oc/client/gui/Robot.scala index a2ad0ec5dd..e69a3987f8 100644 --- a/src/main/scala/li/cil/oc/client/gui/Robot.scala +++ b/src/main/scala/li/cil/oc/client/gui/Robot.scala @@ -1,43 +1,50 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.internal.TextBuffer +import li.cil.oc.client.ComponentTracker import li.cil.oc.client.Textures import li.cil.oc.client.gui.widget.ProgressBar import li.cil.oc.client.renderer.TextBufferRenderCache import li.cil.oc.client.renderer.gui.BufferRenderer import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.container -import li.cil.oc.common.tileentity -import li.cil.oc.integration.opencomputers -import li.cil.oc.util.RenderState -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.INestedGuiEventHandler +import net.minecraft.client.gui.widget.button.Button import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.entity.player.InventoryPlayer -import org.lwjgl.input.Keyboard -import org.lwjgl.input.Mouse +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent +import org.lwjgl.glfw.GLFW import org.lwjgl.opengl.GL11 -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaCollection +import scala.collection.convert.ImplicitConversionsToJava._ -class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) extends DynamicGuiContainer(new container.Robot(playerInventory, robot)) with traits.InputBuffer { - override protected val buffer: TextBuffer = robot.components.collect { - case Some(buffer: api.internal.TextBuffer) => buffer - }.headOption.orNull +class Robot(state: container.Robot, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) + with traits.InputBuffer with INestedGuiEventHandler { - override protected val hasKeyboard: Boolean = robot.info.components.map(api.Driver.driverFor(_, robot.getClass)).contains(opencomputers.DriverKeyboard) + override protected val buffer: TextBuffer = inventoryContainer.info.screenBuffer + .flatMap(ComponentTracker.get(Minecraft.getInstance.level, _)) + .collectFirst { + case buffer: TextBuffer => buffer + }.orNull + + override protected val hasKeyboard: Boolean = inventoryContainer.info.hasKeyboard private val withScreenHeight = 256 private val noScreenHeight = 108 private val deltaY = if (buffer != null) 0 else withScreenHeight - noScreenHeight - xSize = 256 - ySize = 256 - deltaY + imageWidth = 256 + imageHeight = 256 - deltaY protected var powerButton: ImageButton = _ @@ -45,11 +52,11 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten // Scroll offset for robot inventory. private var inventoryOffset = 0 - private var isDragging = false + var isScrolling = false - private def canScroll = robot.inventorySize > 16 + private def canScroll = inventoryContainer.info.mainInvSize > 16 - private def maxOffset = robot.inventorySize / 4 - 4 + private def maxOffset = inventoryContainer.info.mainInvSize / 4 - 4 private val slotSize = 18 @@ -70,142 +77,141 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten private val scrollX = inventoryX + slotSize * 4 + 2 private val scrollY = inventoryY private val scrollWidth = 8 - private val scrollHeight = 94 + private val scrollHeight = 92 - private val power = addWidget(new ProgressBar(26, 156 - deltaY)) + private val power = addCustomWidget(new ProgressBar(26, 156 - deltaY)) private val selectionSize = 20 private val selectionsStates = 17 - private val selectionStepV = 1 / selectionsStates.toDouble - - protected override def actionPerformed(button: GuiButton) { - if (button.id == 0) { - ClientPacketSender.sendComputerPower(robot, !robot.isRunning) - } - } - - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) { - powerButton.toggled = robot.isRunning - scrollButton.enabled = canScroll - scrollButton.hoverOverride = isDragging - if (robot.inventorySize < 16 + inventoryOffset * 4) { - scrollTo(0) + private val selectionStepV = 1 / selectionsStates.toFloat + + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float) { + powerButton.toggled = inventoryContainer.isRunning + scrollButton.active = canScroll + scrollButton.hoverOverride = isScrolling + if (inventoryContainer.info.mainInvSize < 16 + inventoryOffset * 4) { + if (inventoryOffset != 0) scrollTo(0) } - super.drawScreen(mouseX, mouseY, dt) + super.render(stack, mouseX, mouseY, dt) } - override def initGui() { - super.initGui() - powerButton = new ImageButton(0, guiLeft + 5, guiTop + 153 - deltaY, 18, 18, Textures.GUI.ButtonPower, canToggle = true) - scrollButton = new ImageButton(1, guiLeft + scrollX + 1, guiTop + scrollY + 1, 6, 13, Textures.GUI.ButtonScroll) - add(buttonList, powerButton) - add(buttonList, scrollButton) + override protected def init() { + super.init() + powerButton = new ImageButton(leftPos + 5, topPos + 153 - deltaY, 18, 18, new Button.IPressable { + override def onPress(b: Button) = ClientPacketSender.sendRobotPower(inventoryContainer, !inventoryContainer.isRunning) + }, Textures.GUI.ButtonPower, canToggle = true) + scrollButton = new ImageButton(leftPos + scrollX + 1, topPos + scrollY + 1, 6, 13, new Button.IPressable { + override def onPress(b: Button) = () + }, Textures.GUI.ButtonScroll) + addButton(powerButton) + addButton(scrollButton) } - override def drawBuffer() { + override def drawBuffer(stack: MatrixStack) { if (buffer != null) { - GlStateManager.translate(bufferX, bufferY, 0) - RenderState.disableEntityLighting() - GlStateManager.pushMatrix() - GlStateManager.translate(-3, -3, 0) - GlStateManager.color(1, 1, 1, 1) - BufferRenderer.drawBackground() - GlStateManager.popMatrix() - RenderState.makeItBlend() + stack.translate(bufferX, bufferY, 0) + stack.pushPose() + stack.translate(-3, -3, 0) + RenderSystem.color4f(1, 1, 1, 1) + BufferRenderer.drawBackground(stack, bufferRenderWidth.toInt, bufferRenderHeight.toInt, forRobot = true) + stack.popPose() val scaleX = bufferRenderWidth / buffer.renderWidth val scaleY = bufferRenderHeight / buffer.renderHeight - val scale = math.min(scaleX, scaleY) + val scale = math.min(scaleX, scaleY).toFloat if (scaleX > scale) { - GlStateManager.translate(buffer.renderWidth * (scaleX - scale) / 2, 0, 0) + stack.translate(buffer.renderWidth * (scaleX - scale) / 2, 0, 0) } else if (scaleY > scale) { - GlStateManager.translate(0, buffer.renderHeight * (scaleY - scale) / 2, 0) + stack.translate(0, buffer.renderHeight * (scaleY - scale) / 2, 0) } - GlStateManager.scale(scale, scale, scale) - GlStateManager.scale(this.scale, this.scale, 1) - BufferRenderer.drawText(buffer) + stack.scale(scale, scale, scale) + stack.scale(this.scale.toFloat, this.scale.toFloat, 1) + BufferRenderer.drawText(stack, buffer) } } - override protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) { - drawBufferLayer() - RenderState.pushAttrib() - if (isPointInRegion(power.x, power.y, power.width, power.height, mouseX, mouseY)) { + override protected def renderLabels(stack: MatrixStack, mouseX: Int, mouseY: Int) { + drawSecondaryForegroundLayer(stack, mouseX, mouseY) + + for (slot <- 0 until menu.slots.size()) { + drawSlotHighlight(stack, menu.getSlot(slot)) + } + } + + override protected def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) { + drawBufferLayer(stack) + if (isPointInRegion(power.x, power.y, power.width, power.height, mouseX - leftPos, mouseY - topPos)) { val tooltip = new java.util.ArrayList[String] val format = Localization.Computer.Power + ": %d%% (%d/%d)" tooltip.add(format.format( - ((robot.globalBuffer / robot.globalBufferSize) * 100).toInt, - robot.globalBuffer.toInt, - robot.globalBufferSize.toInt)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + 100 * inventoryContainer.globalBuffer / inventoryContainer.globalBufferSize, + inventoryContainer.globalBuffer, inventoryContainer.globalBufferSize)) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } - if (powerButton.isMouseOver) { + if (powerButton.isMouseOver(mouseX, mouseY)) { val tooltip = new java.util.ArrayList[String] - tooltip.addAll(asJavaCollection(if (robot.isRunning) Localization.Computer.TurnOff.lines.toIterable else Localization.Computer.TurnOn.lines.toIterable)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) + tooltip.addAll(asJavaCollection(if (inventoryContainer.isRunning) Localization.Computer.TurnOff.lines.toIterable else Localization.Computer.TurnOn.lines.toIterable)) + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) } - RenderState.popAttrib() } - override protected def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) { - GlStateManager.color(1, 1, 1) + override protected def renderBg(stack: MatrixStack, dt: Float, mouseX: Int, mouseY: Int) { + RenderSystem.color4f(1, 1, 1, 1) if (buffer != null) Textures.bind(Textures.GUI.Robot) else Textures.bind(Textures.GUI.RobotNoScreen) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) - power.level = robot.globalBuffer / robot.globalBufferSize - drawWidgets() - if (robot.inventorySize > 0) { - drawSelection() + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) + power.level = inventoryContainer.globalBuffer.toDouble / inventoryContainer.globalBufferSize + drawWidgets(stack) + if (inventoryContainer.info.mainInvSize > 0) { + drawSelection(stack) } - drawInventorySlots() + drawInventorySlots(stack) } // No custom slots, we just extend DynamicGuiContainer for the highlighting. - override protected def drawSlotBackground(x: Int, y: Int) {} + override protected def drawSlotBackground(stack: MatrixStack, x: Int, y: Int) {} - override protected def keyTyped(char: Char, code: Int) { - if (code == Keyboard.KEY_ESCAPE) { - super.keyTyped(char, code) - } - } - - override protected def mouseClicked(mouseX: Int, mouseY: Int, button: Int) { - super.mouseClicked(mouseX, mouseY, button) - if (canScroll && button == 0 && isCoordinateOverScrollBar(mouseX - guiLeft, mouseY - guiTop)) { - isDragging = true + override def mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean = { + val mx = mouseX.asInstanceOf[Int] + val my = mouseY.asInstanceOf[Int] + if (canScroll && button == GLFW.GLFW_MOUSE_BUTTON_LEFT && isCoordinateOverScrollBar(mx - leftPos, my - topPos)) { + isScrolling = true scrollMouse(mouseY) + true } + else super.mouseClicked(mouseX, mouseY, button) } - override protected def mouseReleased(mouseX: Int, mouseY: Int, button: Int) { - super.mouseReleased(mouseX, mouseY, button) - if (button == 0) { - isDragging = false + override def mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean = { + if (canScroll && button == GLFW.GLFW_MOUSE_BUTTON_LEFT && isScrolling) { + isScrolling = false + return true } + super.mouseReleased(mouseX, mouseY, button) } - override protected def mouseClickMove(mouseX: Int, mouseY: Int, lastButtonClicked: Int, timeSinceMouseClick: Long) { - super.mouseClickMove(mouseX, mouseY, lastButtonClicked, timeSinceMouseClick) - if (isDragging) { + override def mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean = { + if (isScrolling) { scrollMouse(mouseY) + true } + else super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY) } - private def scrollMouse(mouseY: Int) { - scrollTo(math.round((mouseY - guiTop - scrollY + 1 - 6.5) * maxOffset / (scrollHeight - 13.0)).toInt) + private def scrollMouse(mouseY: Double) { + scrollTo(math.round((mouseY - topPos - scrollY + 1 - 6.5) * maxOffset / (scrollHeight - 13.0)).toInt) } - override def handleMouseInput() { - super.handleMouseInput() - if (Mouse.hasWheel && Mouse.getEventDWheel != 0) { - val mouseX = Mouse.getEventX * width / mc.displayWidth - guiLeft - val mouseY = height - Mouse.getEventY * height / mc.displayHeight - 1 - guiTop - if (isCoordinateOverInventory(mouseX, mouseY) || isCoordinateOverScrollBar(mouseX, mouseY)) { - if (math.signum(Mouse.getEventDWheel) < 0) scrollDown() - else scrollUp() - } + override def mouseScrolled(mouseX: Double, mouseY: Double, scroll: Double): Boolean = { + val mx = mouseX.asInstanceOf[Int] - leftPos + val my = mouseY.asInstanceOf[Int] - topPos + if (isCoordinateOverInventory(mx, my) || isCoordinateOverScrollBar(mx, my)) { + if (scroll < 0) scrollDown() + else scrollUp() + true } + else super.mouseScrolled(mouseX, mouseY, scroll) } private def isCoordinateOverInventory(x: Int, y: Int) = @@ -222,57 +228,41 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten private def scrollTo(row: Int) { inventoryOffset = math.max(0, math.min(maxOffset, row)) - for (index <- 4 until 68) { - val slot = inventorySlots.getSlot(index) - val displayIndex = index - inventoryOffset * 4 - 4 - if (displayIndex >= 0 && displayIndex < 16) { - slot.xPos = 1 + inventoryX + (displayIndex % 4) * slotSize - slot.yPos = 1 + inventoryY + (displayIndex / 4) * slotSize - } - else { - // Hide the rest! - slot.xPos = -10000 - slot.yPos = -10000 - } - } - val yMin = guiTop + scrollY + 1 + menu.generateSlotsFor(inventoryOffset) + val yMin = topPos + scrollY + 1 if (maxOffset > 0) { - scrollButton.y = yMin + (scrollHeight - 15) * inventoryOffset / maxOffset + scrollButton.y = yMin + (scrollHeight - 13) * inventoryOffset / maxOffset } else { scrollButton.y = yMin } } - override protected def changeSize(w: Double, h: Double, recompile: Boolean): Double = { + override protected def changeSize(w: Double, h: Double): Double = { val bw = w * TextBufferRenderCache.renderer.charRenderWidth val bh = h * TextBufferRenderCache.renderer.charRenderHeight val scaleX = math.min(bufferRenderWidth / bw, 1) val scaleY = math.min(bufferRenderHeight / bh, 1) - if (recompile) { - BufferRenderer.compileBackground(bufferRenderWidth.toInt, bufferRenderHeight.toInt, forRobot = true) - } math.min(scaleX, scaleY) } - private def drawSelection() { - val slot = robot.selectedSlot - inventoryOffset * 4 + private def drawSelection(stack: MatrixStack) { + val slot = inventoryContainer.selectedSlot - inventoryOffset * 4 if (slot >= 0 && slot < 16) { - RenderState.makeItBlend() Textures.bind(Textures.GUI.RobotSelection) - val now = System.currentTimeMillis() / 1000.0 - val offsetV = ((now - now.toInt) * selectionsStates).toInt * selectionStepV - val x = guiLeft + inventoryX - 1 + (slot % 4) * (selectionSize - 2) - val y = guiTop + inventoryY - 1 + (slot / 4) * (selectionSize - 2) + val now = System.currentTimeMillis() % 1000 / 1000.0f + val offsetV = (now * selectionsStates).toInt * selectionStepV + val x = leftPos + inventoryX - 1 + (slot % 4) * (selectionSize - 2) + val y = topPos + inventoryY - 1 + (slot / 4) * (selectionSize - 2) val t = Tessellator.getInstance - val r = t.getBuffer + val r = t.getBuilder r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x, y, zLevel).tex(0, offsetV).endVertex() - r.pos(x, y + selectionSize, zLevel).tex(0, offsetV + selectionStepV).endVertex() - r.pos(x + selectionSize, y + selectionSize, zLevel).tex(1, offsetV + selectionStepV).endVertex() - r.pos(x + selectionSize, y, zLevel).tex(1, offsetV).endVertex() - t.draw() + r.vertex(stack.last.pose, x, y, getBlitOffset).uv(0, offsetV).endVertex() + r.vertex(stack.last.pose, x, y + selectionSize, getBlitOffset).uv(0, offsetV + selectionStepV).endVertex() + r.vertex(stack.last.pose, x + selectionSize, y + selectionSize, getBlitOffset).uv(1, offsetV + selectionStepV).endVertex() + r.vertex(stack.last.pose, x + selectionSize, y, getBlitOffset).uv(1, offsetV).endVertex() + t.end() } } } diff --git a/src/main/scala/li/cil/oc/client/gui/Screen.scala b/src/main/scala/li/cil/oc/client/gui/Screen.scala index 104b2518a5..5dc7eaf5fe 100644 --- a/src/main/scala/li/cil/oc/client/gui/Screen.scala +++ b/src/main/scala/li/cil/oc/client/gui/Screen.scala @@ -1,13 +1,18 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.api import li.cil.oc.client.renderer.TextBufferRenderCache import li.cil.oc.client.renderer.gui.BufferRenderer -import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import org.lwjgl.input.Mouse +import net.minecraft.client.gui.INestedGuiEventHandler +import net.minecraft.client.gui.screen +import net.minecraft.client.settings.KeyBinding +import net.minecraft.util.text.StringTextComponent +import org.lwjgl.glfw.GLFW + +class Screen(val buffer: api.internal.TextBuffer, val hasMouse: Boolean, val hasKeyboardCallback: () => Boolean, val hasPower: () => Boolean) + extends screen.Screen(StringTextComponent.EMPTY) with traits.InputBuffer with INestedGuiEventHandler { -class Screen(val buffer: api.internal.TextBuffer, val hasMouse: Boolean, val hasKeyboardCallback: () => Boolean, val hasPower: () => Boolean) extends traits.InputBuffer { override protected def hasKeyboard = hasKeyboardCallback() override protected def bufferX = 8 + x @@ -20,56 +25,60 @@ class Screen(val buffer: api.internal.TextBuffer, val hasMouse: Boolean, val has private var x, y = 0 + private var innerWidth, innerHeight = 0 + private var mx, my = -1 - override def handleMouseInput() { - super.handleMouseInput() - if (hasMouse && Mouse.hasWheel && Mouse.getEventDWheel != 0) { - val mouseX = Mouse.getEventX * width / mc.displayWidth - val mouseY = height - Mouse.getEventY * height / mc.displayHeight - 1 + override def mouseScrolled(mouseX: Double, mouseY: Double, scroll: Double): Boolean = { + if (hasMouse) { toBufferCoordinates(mouseX, mouseY) match { case Some((bx, by)) => - val scroll = math.signum(Mouse.getEventDWheel) - buffer.mouseScroll(bx, by, scroll, null) + buffer.mouseScroll(bx, by, math.signum(scroll).asInstanceOf[Int], null) + return true case _ => // Ignore when out of bounds. } } + super.mouseScrolled(mouseX, mouseY, scroll) } - override protected def mouseClicked(mouseX: Int, mouseY: Int, button: Int) { - super.mouseClicked(mouseX, mouseY, button) + override def mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean = { if (hasMouse) { - if (button == 0 || button == 1) { + if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT || button == GLFW.GLFW_MOUSE_BUTTON_RIGHT) { clickOrDrag(mouseX, mouseY, button) + return true } } + super.mouseClicked(mouseX, mouseY, button) } - protected override def mouseClickMove(mouseX: Int, mouseY: Int, button: Int, timeSinceLast: Long) { - super.mouseClickMove(mouseX, mouseY, button, timeSinceLast) - if (hasMouse && timeSinceLast > 10) { - if (button == 0 || button == 1) { + override def mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean = { + if (hasMouse) { + if (button == GLFW.GLFW_MOUSE_BUTTON_LEFT || button == GLFW.GLFW_MOUSE_BUTTON_RIGHT) { clickOrDrag(mouseX, mouseY, button) + return true } } + super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY) } - override protected def mouseReleased(mouseX: Int, mouseY: Int, button: Int) { - super.mouseReleased(mouseX, mouseY, button) - if (hasMouse && button >= 0) { + override def mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean = { + if (hasMouse) { if (didClick) { toBufferCoordinates(mouseX, mouseY) match { case Some((bx, by)) => buffer.mouseUp(bx, by, button, null) case _ => buffer.mouseUp(-1.0, -1.0, button, null) } } + val hasClicked = didClick didClick = false mx = -1 my = -1 + if (hasClicked) return true } + super.mouseReleased(mouseX, mouseY, button) } - private def clickOrDrag(mouseX: Int, mouseY: Int, button: Int) { + private def clickOrDrag(mouseX: Double, mouseY: Double, button: Int) { toBufferCoordinates(mouseX, mouseY) match { case Some((bx, by)) if bx.toInt != mx || (by*2).toInt != my => if (mx >= 0 && my >= 0) buffer.mouseDrag(bx, by, button, null) @@ -81,7 +90,7 @@ class Screen(val buffer: api.internal.TextBuffer, val hasMouse: Boolean, val has } } - private def toBufferCoordinates(mouseX: Int, mouseY: Int): Option[(Double, Double)] = { + private def toBufferCoordinates(mouseX: Double, mouseY: Double): Option[(Double, Double)] = { val bx = (mouseX - x - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderWidth val by = (mouseY - y - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderHeight val bw = buffer.getViewportWidth @@ -90,35 +99,37 @@ class Screen(val buffer: api.internal.TextBuffer, val hasMouse: Boolean, val has else None } - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float): Unit = { - super.drawScreen(mouseX, mouseY, dt) - drawBufferLayer() + override protected def init(): Unit = { + super.init() + minecraft.mouseHandler.releaseMouse() + KeyBinding.releaseAll() } - override def drawBuffer() { - GlStateManager.translate(x, y, 0) - BufferRenderer.drawBackground() + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float): Unit = { + super.render(stack, mouseX, mouseY, dt) + drawBufferLayer(stack) + } + + override def drawBuffer(stack: MatrixStack) { + stack.translate(x, y, 0) + BufferRenderer.drawBackground(stack, innerWidth, innerHeight) if (hasPower()) { - GlStateManager.translate(bufferMargin, bufferMargin, 0) - GlStateManager.scale(scale, scale, 1) - RenderState.makeItBlend() - BufferRenderer.drawText(buffer) + stack.translate(bufferMargin, bufferMargin, 0) + stack.scale(scale.toFloat, scale.toFloat, 1) + BufferRenderer.drawText(stack, buffer) } } - override protected def changeSize(w: Double, h: Double, recompile: Boolean) = { + override protected def changeSize(w: Double, h: Double) = { val bw = buffer.renderWidth val bh = buffer.renderHeight val scaleX = math.min(width / (bw + bufferMargin * 2.0), 1) val scaleY = math.min(height / (bh + bufferMargin * 2.0), 1) val scale = math.min(scaleX, scaleY) - val innerWidth = (bw * scale).toInt - val innerHeight = (bh * scale).toInt + innerWidth = (bw * scale).toInt + innerHeight = (bh * scale).toInt x = (width - (innerWidth + bufferMargin * 2)) / 2 y = (height - (innerHeight + bufferMargin * 2)) / 2 - if (recompile) { - BufferRenderer.compileBackground(innerWidth, innerHeight) - } scale } } diff --git a/src/main/scala/li/cil/oc/client/gui/Server.scala b/src/main/scala/li/cil/oc/client/gui/Server.scala index 98f4af99cf..4d7ad48268 100644 --- a/src/main/scala/li/cil/oc/client/gui/Server.scala +++ b/src/main/scala/li/cil/oc/client/gui/Server.scala @@ -1,67 +1,54 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.client.Textures import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.container -import li.cil.oc.common.inventory.ServerInventory -import li.cil.oc.common.tileentity import net.minecraft.client.Minecraft -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.client.gui.widget.button.Button +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -import scala.collection.convert.WrapAsJava.asJavaCollection +import scala.collection.JavaConverters.asJavaCollection -class Server(playerInventory: InventoryPlayer, serverInventory: ServerInventory, val rack: Option[tileentity.Rack] = None, val slot: Int = 0) extends DynamicGuiContainer(new container.Server(playerInventory, serverInventory)) with traits.LockedHotbar { - protected var powerButton: ImageButton = _ - - override def lockedStack = serverInventory.container +class Server(state: container.Server, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) + with traits.LockedHotbar[container.Server] { - protected override def actionPerformed(button: GuiButton) { - if (button.id == 0) { - rack match { - case Some(t) => ClientPacketSender.sendServerPower(t, slot, !inventoryContainer.isRunning) - case _ => - } - } - } + protected var powerButton: ImageButton = _ - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float) { - // Close GUI if item is removed from rack. - rack match { - case Some(t) if t.getStackInSlot(slot) != serverInventory.container => - Minecraft.getMinecraft.displayGuiScreen(null) - return - case _ => - } + override def lockedStack = inventoryContainer.stack + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float) { powerButton.visible = !inventoryContainer.isItem powerButton.toggled = inventoryContainer.isRunning - super.drawScreen(mouseX, mouseY, dt) + super.render(stack, mouseX, mouseY, dt) } - override def initGui() { - super.initGui() - powerButton = new ImageButton(0, guiLeft + 48, guiTop + 33, 18, 18, Textures.GUI.ButtonPower, canToggle = true) - add(buttonList, powerButton) + override protected def init() { + super.init() + powerButton = new ImageButton(leftPos + 48, topPos + 33, 18, 18, new Button.IPressable { + override def onPress(b: Button) = if (inventoryContainer.rackSlot >= 0) { + ClientPacketSender.sendServerPower(inventoryContainer, inventoryContainer.rackSlot, !inventoryContainer.isRunning) + } + }, Textures.GUI.ButtonPower, canToggle = true) + addButton(powerButton) } - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(serverInventory.getName), - 8, 6, 0x404040) - if (powerButton.isMouseOver) { + override def drawSecondaryForegroundLayer(stack: MatrixStack, mouseX: Int, mouseY: Int) { + super.drawSecondaryForegroundLayer(stack, mouseX, mouseY) + if (powerButton.isMouseOver(mouseX, mouseY)) { val tooltip = new java.util.ArrayList[String] tooltip.addAll(asJavaCollection(if (inventoryContainer.isRunning) Localization.Computer.TurnOff.lines.toIterable else Localization.Computer.TurnOn.lines.toIterable)) - copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRenderer) - } + copiedDrawHoveringText(stack, tooltip, mouseX - leftPos, mouseY - topPos, font) + } } - override def drawSecondaryBackgroundLayer() { - GlStateManager.color(1, 1, 1) + override def drawSecondaryBackgroundLayer(stack: MatrixStack) { + RenderSystem.color3f(1, 1, 1) Textures.bind(Textures.GUI.Server) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) } } diff --git a/src/main/scala/li/cil/oc/client/gui/Tablet.scala b/src/main/scala/li/cil/oc/client/gui/Tablet.scala index 94a934ed52..d0816a535e 100644 --- a/src/main/scala/li/cil/oc/client/gui/Tablet.scala +++ b/src/main/scala/li/cil/oc/client/gui/Tablet.scala @@ -1,17 +1,12 @@ package li.cil.oc.client.gui -import li.cil.oc.Localization import li.cil.oc.common.container -import li.cil.oc.common.item.TabletWrapper -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.util.text.ITextComponent -class Tablet(playerInventory: InventoryPlayer, val tablet: TabletWrapper) extends DynamicGuiContainer(new container.Tablet(playerInventory, tablet)) with traits.LockedHotbar { - override def lockedStack = tablet.stack +class Tablet(state: container.Tablet, playerInventory: PlayerInventory, name: ITextComponent) + extends DynamicGuiContainer(state, playerInventory, name) + with traits.LockedHotbar[container.Tablet] { - override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = { - super.drawSecondaryForegroundLayer(mouseX, mouseY) - fontRenderer.drawString( - Localization.localizeImmediately(tablet.getName), - 8, 6, 0x404040) - } + override def lockedStack = inventoryContainer.stack } diff --git a/src/main/scala/li/cil/oc/client/gui/Waypoint.scala b/src/main/scala/li/cil/oc/client/gui/Waypoint.scala index 6cee5dc1d6..e979cf3702 100644 --- a/src/main/scala/li/cil/oc/client/gui/Waypoint.scala +++ b/src/main/scala/li/cil/oc/client/gui/Waypoint.scala @@ -1,78 +1,77 @@ package li.cil.oc.client.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.PacketSender import li.cil.oc.client.Textures import li.cil.oc.common.tileentity -import li.cil.oc.util.OldScaledResolution -import net.minecraft.client.gui.GuiScreen -import net.minecraft.client.gui.GuiTextField -import net.minecraft.client.gui.ScaledResolution -import net.minecraft.client.renderer.GlStateManager -import org.lwjgl.input.Keyboard +import net.minecraft.client.gui.screen +import net.minecraft.client.gui.widget.TextFieldWidget +import net.minecraft.client.settings.KeyBinding +import net.minecraft.util.text.StringTextComponent +import org.lwjgl.glfw.GLFW -class Waypoint(val waypoint: tileentity.Waypoint) extends GuiScreen { - var guiLeft = 0 - var guiTop = 0 - var xSize = 0 - var ySize = 0 +class Waypoint(val waypoint: tileentity.Waypoint) extends screen.Screen(StringTextComponent.EMPTY) { + val imageWidth = 176 + val imageHeight = 24 + var leftPos = 0 + var topPos = 0 + passEvents = false - var textField: GuiTextField = _ + var textField: TextFieldWidget = _ - override def updateScreen(): Unit = { - super.updateScreen() - if (mc.player.getDistanceSq(waypoint.x + 0.5, waypoint.y + 0.5, waypoint.z + 0.5) > 64) { - mc.player.closeScreen() + override def tick(): Unit = { + super.tick() + textField.tick() + if (minecraft.player.distanceToSqr(waypoint.x + 0.5, waypoint.y + 0.5, waypoint.z + 0.5) > 64) { + onClose() } } - override def doesGuiPauseGame(): Boolean = false + override def isPauseScreen(): Boolean = false - override def initGui(): Unit = { - super.initGui() + override protected def init(): Unit = { + super.init() + minecraft.mouseHandler.releaseMouse() + KeyBinding.releaseAll() + leftPos = (width - imageWidth) / 2 + topPos = (height - imageHeight) / 2 - val screenSize = new ScaledResolution(mc) - val guiSize = new OldScaledResolution(mc, 176, 24) - val (midX, midY) = (screenSize.getScaledWidth / 2, screenSize.getScaledHeight / 2) - guiLeft = midX - guiSize.getScaledWidth / 2 - guiTop = midY - guiSize.getScaledHeight / 2 - xSize = guiSize.getScaledWidth - ySize = guiSize.getScaledHeight - - textField = new GuiTextField(0, fontRenderer, guiLeft + 7, guiTop + 8, 164 - 12, 12) - textField.setMaxStringLength(32) - textField.setEnableBackgroundDrawing(false) + textField = new TextFieldWidget(font, leftPos + 7, topPos + 8, 164 - 12, 12, StringTextComponent.EMPTY) { + override def keyPressed(keyCode: Int, scanCode: Int, mods: Int): Boolean = { + if (keyCode == GLFW.GLFW_KEY_ENTER) { + val label = textField.getValue.take(32) + if (label != waypoint.label) { + waypoint.label = label + PacketSender.sendWaypointLabel(waypoint) + onClose() + } + return true + } + super.keyPressed(keyCode, scanCode, mods) + } + } + textField.setMaxLength(32) + textField.setBordered(false) textField.setCanLoseFocus(false) - textField.setFocused(true) textField.setTextColor(0xFFFFFF) - textField.setText(waypoint.label) + textField.setValue(waypoint.label) + addWidget(textField) - Keyboard.enableRepeatEvents(true) + setInitialFocus(textField) + minecraft.keyboardHandler.setSendRepeatsToGui(true) } - override def onGuiClosed(): Unit = { - super.onGuiClosed() - Keyboard.enableRepeatEvents(false) - } - - override def keyTyped(char: Char, code: Int): Unit = { - if (!textField.textboxKeyTyped(char, code)) { - if (code == Keyboard.KEY_RETURN) { - val label = textField.getText.take(32) - if (label != waypoint.label) { - waypoint.label = label - PacketSender.sendWaypointLabel(waypoint) - mc.player.closeScreen() - } - } - else super.keyTyped(char, code) - } + override def removed(): Unit = { + minecraft.keyboardHandler.setSendRepeatsToGui(false) + super.removed() } - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float): Unit = { - super.drawScreen(mouseX, mouseY, dt) - GlStateManager.color(1, 1, 1) // Required under Linux. - mc.renderEngine.bindTexture(Textures.GUI.Waypoint) - drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize) - textField.drawTextBox() + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float): Unit = { + super.render(stack, mouseX, mouseY, dt) + RenderSystem.color3f(1, 1, 1) // Required under Linux. + minecraft.getTextureManager.bind(Textures.GUI.Waypoint) + blit(stack, leftPos, topPos, 0, 0, imageWidth, imageHeight) + textField.render(stack, mouseX, mouseY, dt) } } diff --git a/src/main/scala/li/cil/oc/client/gui/traits/DisplayBuffer.scala b/src/main/scala/li/cil/oc/client/gui/traits/DisplayBuffer.scala index 05fe40575f..7069895a62 100644 --- a/src/main/scala/li/cil/oc/client/gui/traits/DisplayBuffer.scala +++ b/src/main/scala/li/cil/oc/client/gui/traits/DisplayBuffer.scala @@ -1,12 +1,10 @@ package li.cil.oc.client.gui.traits -import li.cil.oc.client.renderer.gui.BufferRenderer +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.util.RenderState -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.GuiScreen -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.gui.screen.Screen -trait DisplayBuffer extends GuiScreen { +trait DisplayBuffer extends Screen { protected def bufferX: Int protected def bufferY: Int @@ -15,36 +13,21 @@ trait DisplayBuffer extends GuiScreen { protected def bufferRows: Int - protected var guiSizeChanged = false - - protected var currentWidth, currentHeight = -1 - protected var scale = 0.0 - override def initGui() = { - super.initGui() - BufferRenderer.init(Minecraft.getMinecraft.renderEngine) - guiSizeChanged = true - } - - protected def drawBufferLayer() { - val oldWidth = currentWidth - val oldHeight = currentHeight - currentWidth = bufferColumns - currentHeight = bufferRows - scale = changeSize(currentWidth, currentHeight, guiSizeChanged || oldWidth != currentWidth || oldHeight != currentHeight) + protected def drawBufferLayer(stack: MatrixStack) { + scale = changeSize(bufferColumns, bufferRows) RenderState.checkError(getClass.getName + ".drawBufferLayer: entering (aka: wasntme)") - GlStateManager.pushMatrix() - RenderState.disableEntityLighting() - drawBuffer() - GlStateManager.popMatrix() + stack.pushPose() + drawBuffer(stack) + stack.popPose() RenderState.checkError(getClass.getName + ".drawBufferLayer: buffer layer") } - protected def drawBuffer(): Unit + protected def drawBuffer(stack: MatrixStack): Unit - protected def changeSize(w: Double, h: Double, recompile: Boolean): Double + protected def changeSize(w: Double, h: Double): Double } diff --git a/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala b/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala index e80873bdd3..4e9b7530ce 100644 --- a/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala +++ b/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala @@ -1,16 +1,20 @@ package li.cil.oc.client.gui.traits +import java.util.Arrays + +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.api import li.cil.oc.client.KeyBindings import li.cil.oc.client.Textures import li.cil.oc.integration.util.ItemSearch import li.cil.oc.util.RenderState -import net.minecraft.client.gui.GuiScreen -import net.minecraft.client.gui.inventory.GuiContainer -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.screen.Screen +import net.minecraft.client.gui.screen.inventory.ContainerScreen import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import org.lwjgl.input.Keyboard +import net.minecraft.client.util.InputMappings +import org.lwjgl.glfw.GLFW import org.lwjgl.opengl.GL11 import scala.collection.mutable @@ -28,98 +32,316 @@ trait InputBuffer extends DisplayBuffer { private var showKeyboardMissing = 0L - override def doesGuiPauseGame = false + private var hasQueuedKey = false + private var queuedKey = 0 + private var queuedChar = '\u0000' + private var highSurrogate = '\u0000' + + protected def pushQueuedKey(keyCode: Int): Unit = { + flushQueuedKey() + hasQueuedKey = true + queuedKey = keyCode + queuedChar = GLFWTranslator.keyToChar(keyCode) + } + + protected def pushQueuedChar(char: Char): Unit = { + if (hasQueuedKey) { + if (!Character.isSurrogate(char)) queuedChar = char + // Flush either way as the next code point will be unrelated. + flushQueuedKey() + } + // text_input happens independent of key events + if (Character.isSurrogate(char)) { + // Convert two successive surrogates back into a code point. + if (Character.isHighSurrogate(char)) highSurrogate = char + else buffer.textInput(Character.toCodePoint(highSurrogate, char), null) + } + else buffer.textInput(char, null) + } - override def initGui() = { - super.initGui() - Keyboard.enableRepeatEvents(true) + protected def flushQueuedKey(): Unit = { + if (hasQueuedKey) { + hasQueuedKey = false + if (!pressedKeys.contains(queuedKey)) { + val lwjglCode = GLFWTranslator.glfwToLWJGL(queuedKey) + if (lwjglCode > 0) { + pressedKeys(queuedKey) = queuedChar + if (buffer != null) buffer.keyDown(queuedChar, lwjglCode, null) + } + else if (queuedChar > 0) { + pressedKeys(queuedKey) = queuedChar + if (buffer != null) buffer.keyDown(queuedChar, 0, null) + } + } + } } - override protected def drawBufferLayer() { - super.drawBufferLayer() + override def isPauseScreen = false + + override protected def init() = { + super.init() + Minecraft.getInstance.keyboardHandler.setSendRepeatsToGui(true) + } + + override protected def drawBufferLayer(stack: MatrixStack) { + super.drawBufferLayer(stack) if (System.currentTimeMillis() - showKeyboardMissing < 1000) { Textures.bind(Textures.GUI.KeyboardMissing) - GlStateManager.disableDepth() val x = bufferX + buffer.renderWidth - 16 val y = bufferY + buffer.renderHeight - 16 val t = Tessellator.getInstance - val r = t.getBuffer + val r = t.getBuilder r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x, y + 16, 0).tex(0, 1).endVertex() - r.pos(x + 16, y + 16, 0).tex(1, 1).endVertex() - r.pos(x + 16, y, 0).tex(1, 0).endVertex() - r.pos(x, y, 0).tex(0, 0).endVertex() - t.draw() - - GlStateManager.enableDepth() + r.vertex(stack.last.pose, x, y + 16, 0).uv(0, 1).endVertex() + r.vertex(stack.last.pose, x + 16, y + 16, 0).uv(1, 1).endVertex() + r.vertex(stack.last.pose, x + 16, y, 0).uv(1, 0).endVertex() + r.vertex(stack.last.pose, x, y, 0).uv(0, 0).endVertex() + t.end() RenderState.checkError(getClass.getName + ".drawBufferLayer: keyboard icon") } } - override def onGuiClosed() = { - super.onGuiClosed() - if (buffer != null) for ((code, char) <- pressedKeys) { - buffer.keyUp(char, code, null) - } - Keyboard.enableRepeatEvents(false) + override def tick(): Unit = { + super.tick() + flushQueuedKey() } - override def handleKeyboardInput() { - super.handleKeyboardInput() + override def removed() = { + super.removed() + Minecraft.getInstance.keyboardHandler.setSendRepeatsToGui(false) + if (buffer != null) { + flushQueuedKey() + for ((code, char) <- pressedKeys) { + val lwjglCode = GLFWTranslator.glfwToLWJGL(code) + if (lwjglCode > 0) buffer.keyUp(char, lwjglCode, null) + else buffer.keyUp(char, 0, null) + } + } + } - if (this.isInstanceOf[GuiContainer] && ItemSearch.isInputFocused) return + def onInput(input: InputMappings.Input): Boolean = { + if (KeyBindings.clipboardPaste.isActiveAndMatches(input)) { + if (buffer != null) { + if (hasKeyboard) buffer.clipboard(Minecraft.getInstance.keyboardHandler.getClipboard, null) + else showKeyboardMissing = System.currentTimeMillis() + } + return true + } + false + } - val code = Keyboard.getEventKey - if (buffer != null && code != Keyboard.KEY_ESCAPE && code != Keyboard.KEY_F11) { - if (hasKeyboard) { - if (Keyboard.getEventKeyState) { - val char = Keyboard.getEventCharacter - if (!pressedKeys.contains(code) || !ignoreRepeat(char, code)) { - buffer.keyDown(char, code, null) - pressedKeys += code -> char - } - } - else pressedKeys.remove(code) match { - case Some(char) => buffer.keyUp(char, code, null) - case _ => // Wasn't pressed while viewing the screen. - } + override def charTyped(codePt: Char, mods: Int): Boolean = { + if (!this.isInstanceOf[ContainerScreen[_]] || !ItemSearch.isInputFocused) { + if (buffer != null) { + if (hasKeyboard) pushQueuedChar(codePt) + else showKeyboardMissing = System.currentTimeMillis() + return true + } + } + super.charTyped(codePt, mods) + } - if (KeyBindings.isPastingClipboard) { - buffer.clipboard(GuiScreen.getClipboardString, null) - } + override def keyPressed(keyCode: Int, scanCode: Int, mods: Int): Boolean = { + if (!this.isInstanceOf[ContainerScreen[_]] || !ItemSearch.isInputFocused) { + if (keyCode == GLFW.GLFW_KEY_ESCAPE && shouldCloseOnEsc) { + onClose() + return true } - else { - showKeyboardMissing = System.currentTimeMillis() + if (onInput(InputMappings.getKey(keyCode, scanCode))) return true + if (buffer != null && keyCode != GLFW.GLFW_KEY_UNKNOWN) { + if (hasKeyboard) pushQueuedKey(keyCode) + else showKeyboardMissing = System.currentTimeMillis() + return true } } + super.keyPressed(keyCode, scanCode, mods) } - override protected def mouseClicked(x: Int, y: Int, button: Int) { - super.mouseClicked(x, y, button) - val isMiddleMouseButton = button == 2 - val isBoundMouseButton = KeyBindings.isPastingClipboard - if (buffer != null && (isMiddleMouseButton || isBoundMouseButton)) { - if (hasKeyboard) { - buffer.clipboard(GuiScreen.getClipboardString, null) - } - else { - showKeyboardMissing = System.currentTimeMillis() + override def keyReleased(keyCode: Int, scanCode: Int, mods: Int): Boolean = { + if (!this.isInstanceOf[ContainerScreen[_]] || !ItemSearch.isInputFocused) { + flushQueuedKey() + pressedKeys.remove(keyCode) match { + case Some(char) => { + val lwjglCode = GLFWTranslator.glfwToLWJGL(keyCode) + if (lwjglCode > 0) { + buffer.keyUp(char, lwjglCode, null) + return true + } + else if (char > 0) { + buffer.keyUp(char, 0, null) + return true + } + } + case None => } + // Wasn't pressed while viewing the screen. } + super.keyReleased(keyCode, scanCode, mods) } - private def ignoreRepeat(char: Char, code: Int) = { - code == Keyboard.KEY_LCONTROL || - code == Keyboard.KEY_RCONTROL || - code == Keyboard.KEY_LMENU || - code == Keyboard.KEY_RMENU || - code == Keyboard.KEY_LSHIFT || - code == Keyboard.KEY_RSHIFT || - code == Keyboard.KEY_LMETA || - code == Keyboard.KEY_RMETA + override def mouseClicked(x: Double, y: Double, button: Int): Boolean = { + if (onInput(InputMappings.Type.MOUSE.getOrCreate(button))) return true + if (buffer != null && button == GLFW.GLFW_MOUSE_BUTTON_MIDDLE) { + if (hasKeyboard) buffer.clipboard(Minecraft.getInstance.keyboardHandler.getClipboard, null) + else showKeyboardMissing = System.currentTimeMillis() + return true + } + super.mouseClicked(x, y, button) + } + + private def ignoreRepeat(keyCode: Int) = { + keyCode == GLFW.GLFW_KEY_LEFT_CONTROL || + keyCode == GLFW.GLFW_KEY_RIGHT_CONTROL || + keyCode == GLFW.GLFW_KEY_MENU || + keyCode == GLFW.GLFW_KEY_LEFT_ALT || + keyCode == GLFW.GLFW_KEY_RIGHT_ALT || + keyCode == GLFW.GLFW_KEY_LEFT_SHIFT || + keyCode == GLFW.GLFW_KEY_RIGHT_SHIFT || + keyCode == GLFW.GLFW_KEY_LEFT_SUPER || + keyCode == GLFW.GLFW_KEY_RIGHT_SUPER + } +} + +object GLFWTranslator { + private val toLWJGL = new Array[Int](GLFW.GLFW_KEY_LAST + 1) + Arrays.fill(toLWJGL, -1) + + /** Printable keys. */ + toLWJGL(GLFW.GLFW_KEY_SPACE) = 0x39 + toLWJGL(GLFW.GLFW_KEY_APOSTROPHE) = 0x28 + toLWJGL(GLFW.GLFW_KEY_COMMA) = 0x33 + toLWJGL(GLFW.GLFW_KEY_MINUS) = 0x0C + toLWJGL(GLFW.GLFW_KEY_PERIOD) = 0x34 + toLWJGL(GLFW.GLFW_KEY_SLASH) = 0x35 + toLWJGL(GLFW.GLFW_KEY_0) = 0x0B + toLWJGL(GLFW.GLFW_KEY_1) = 0x02 + toLWJGL(GLFW.GLFW_KEY_2) = 0x03 + toLWJGL(GLFW.GLFW_KEY_3) = 0x04 + toLWJGL(GLFW.GLFW_KEY_4) = 0x05 + toLWJGL(GLFW.GLFW_KEY_5) = 0x06 + toLWJGL(GLFW.GLFW_KEY_6) = 0x07 + toLWJGL(GLFW.GLFW_KEY_7) = 0x08 + toLWJGL(GLFW.GLFW_KEY_8) = 0x09 + toLWJGL(GLFW.GLFW_KEY_9) = 0x0A + toLWJGL(GLFW.GLFW_KEY_SEMICOLON) = 0x27 + toLWJGL(GLFW.GLFW_KEY_EQUAL) = 0x0D + toLWJGL(GLFW.GLFW_KEY_A) = 0x1E + toLWJGL(GLFW.GLFW_KEY_B) = 0x30 + toLWJGL(GLFW.GLFW_KEY_C) = 0x2E + toLWJGL(GLFW.GLFW_KEY_D) = 0x20 + toLWJGL(GLFW.GLFW_KEY_E) = 0x12 + toLWJGL(GLFW.GLFW_KEY_F) = 0x21 + toLWJGL(GLFW.GLFW_KEY_G) = 0x22 + toLWJGL(GLFW.GLFW_KEY_H) = 0x23 + toLWJGL(GLFW.GLFW_KEY_I) = 0x17 + toLWJGL(GLFW.GLFW_KEY_J) = 0x24 + toLWJGL(GLFW.GLFW_KEY_K) = 0x25 + toLWJGL(GLFW.GLFW_KEY_L) = 0x26 + toLWJGL(GLFW.GLFW_KEY_M) = 0x32 + toLWJGL(GLFW.GLFW_KEY_N) = 0x31 + toLWJGL(GLFW.GLFW_KEY_O) = 0x18 + toLWJGL(GLFW.GLFW_KEY_P) = 0x19 + toLWJGL(GLFW.GLFW_KEY_Q) = 0x10 + toLWJGL(GLFW.GLFW_KEY_R) = 0x13 + toLWJGL(GLFW.GLFW_KEY_S) = 0x1F + toLWJGL(GLFW.GLFW_KEY_T) = 0x14 + toLWJGL(GLFW.GLFW_KEY_U) = 0x16 + toLWJGL(GLFW.GLFW_KEY_V) = 0x2F + toLWJGL(GLFW.GLFW_KEY_W) = 0x11 + toLWJGL(GLFW.GLFW_KEY_X) = 0x2D + toLWJGL(GLFW.GLFW_KEY_Y) = 0x15 + toLWJGL(GLFW.GLFW_KEY_Z) = 0x2C + toLWJGL(GLFW.GLFW_KEY_LEFT_BRACKET) = 0x1A + toLWJGL(GLFW.GLFW_KEY_BACKSLASH) = 0x2B + toLWJGL(GLFW.GLFW_KEY_RIGHT_BRACKET) = 0x1B + toLWJGL(GLFW.GLFW_KEY_GRAVE_ACCENT) = 0x29 + toLWJGL(GLFW.GLFW_KEY_WORLD_1) = 0x00 + toLWJGL(GLFW.GLFW_KEY_WORLD_2) = 0x00 + + /** Function keys. */ + toLWJGL(GLFW.GLFW_KEY_ESCAPE) = 0x01 + toLWJGL(GLFW.GLFW_KEY_ENTER) = 0x1C + toLWJGL(GLFW.GLFW_KEY_TAB) = 0x0F + toLWJGL(GLFW.GLFW_KEY_BACKSPACE) = 0x0E + toLWJGL(GLFW.GLFW_KEY_INSERT) = 0xD2 + toLWJGL(GLFW.GLFW_KEY_DELETE) = 0xD3 + toLWJGL(GLFW.GLFW_KEY_RIGHT) = 0xCD + toLWJGL(GLFW.GLFW_KEY_LEFT) = 0xCB + toLWJGL(GLFW.GLFW_KEY_DOWN) = 0xD0 + toLWJGL(GLFW.GLFW_KEY_UP) = 0xC8 + toLWJGL(GLFW.GLFW_KEY_PAGE_UP) = 0xC9 + toLWJGL(GLFW.GLFW_KEY_PAGE_DOWN) = 0xD1 + toLWJGL(GLFW.GLFW_KEY_HOME) = 0xC7 + toLWJGL(GLFW.GLFW_KEY_END) = 0xCF + toLWJGL(GLFW.GLFW_KEY_CAPS_LOCK) = 0x3A + toLWJGL(GLFW.GLFW_KEY_SCROLL_LOCK) = 0x46 + toLWJGL(GLFW.GLFW_KEY_NUM_LOCK) = 0x45 + toLWJGL(GLFW.GLFW_KEY_PRINT_SCREEN) = 0xB7 + toLWJGL(GLFW.GLFW_KEY_PAUSE) = 0xC5 + toLWJGL(GLFW.GLFW_KEY_F1) = 0x3B + toLWJGL(GLFW.GLFW_KEY_F2) = 0x3C + toLWJGL(GLFW.GLFW_KEY_F3) = 0x3D + toLWJGL(GLFW.GLFW_KEY_F4) = 0x3E + toLWJGL(GLFW.GLFW_KEY_F5) = 0x3F + toLWJGL(GLFW.GLFW_KEY_F6) = 0x40 + toLWJGL(GLFW.GLFW_KEY_F7) = 0x41 + toLWJGL(GLFW.GLFW_KEY_F8) = 0x42 + toLWJGL(GLFW.GLFW_KEY_F9) = 0x43 + toLWJGL(GLFW.GLFW_KEY_F10) = 0x44 + toLWJGL(GLFW.GLFW_KEY_F11) = 0x57 + toLWJGL(GLFW.GLFW_KEY_F12) = 0x58 + toLWJGL(GLFW.GLFW_KEY_F13) = 0x64 + toLWJGL(GLFW.GLFW_KEY_F14) = 0x65 + toLWJGL(GLFW.GLFW_KEY_F15) = 0x66 + toLWJGL(GLFW.GLFW_KEY_F16) = 0x67 + toLWJGL(GLFW.GLFW_KEY_F17) = 0x68 + toLWJGL(GLFW.GLFW_KEY_F18) = 0x69 + toLWJGL(GLFW.GLFW_KEY_F19) = 0x71 + toLWJGL(GLFW.GLFW_KEY_F20) = -1 + toLWJGL(GLFW.GLFW_KEY_F21) = -1 + toLWJGL(GLFW.GLFW_KEY_F22) = -1 + toLWJGL(GLFW.GLFW_KEY_F23) = -1 + toLWJGL(GLFW.GLFW_KEY_F24) = -1 + toLWJGL(GLFW.GLFW_KEY_F25) = -1 + toLWJGL(GLFW.GLFW_KEY_KP_0) = 0x52 + toLWJGL(GLFW.GLFW_KEY_KP_1) = 0x4F + toLWJGL(GLFW.GLFW_KEY_KP_2) = 0x50 + toLWJGL(GLFW.GLFW_KEY_KP_3) = 0x51 + toLWJGL(GLFW.GLFW_KEY_KP_4) = 0x4B + toLWJGL(GLFW.GLFW_KEY_KP_5) = 0x4C + toLWJGL(GLFW.GLFW_KEY_KP_6) = 0x4D + toLWJGL(GLFW.GLFW_KEY_KP_7) = 0x47 + toLWJGL(GLFW.GLFW_KEY_KP_8) = 0x48 + toLWJGL(GLFW.GLFW_KEY_KP_9) = 0x49 + toLWJGL(GLFW.GLFW_KEY_KP_DECIMAL) = 0x53 + toLWJGL(GLFW.GLFW_KEY_KP_DIVIDE) = 0xB5 + toLWJGL(GLFW.GLFW_KEY_KP_MULTIPLY) = 0x37 + toLWJGL(GLFW.GLFW_KEY_KP_SUBTRACT) = 0x4A + toLWJGL(GLFW.GLFW_KEY_KP_ADD) = 0x4E + toLWJGL(GLFW.GLFW_KEY_KP_ENTER) = 0x9C + toLWJGL(GLFW.GLFW_KEY_KP_EQUAL) = 0x8D + toLWJGL(GLFW.GLFW_KEY_LEFT_SHIFT) = 0x2A + toLWJGL(GLFW.GLFW_KEY_LEFT_CONTROL) = 0x1D + toLWJGL(GLFW.GLFW_KEY_LEFT_ALT) = 0x38 + toLWJGL(GLFW.GLFW_KEY_LEFT_SUPER) = 0xDB + toLWJGL(GLFW.GLFW_KEY_RIGHT_SHIFT) = 0x36 + toLWJGL(GLFW.GLFW_KEY_RIGHT_CONTROL) = 0x9D + toLWJGL(GLFW.GLFW_KEY_RIGHT_ALT) = 0xB8 + toLWJGL(GLFW.GLFW_KEY_RIGHT_SUPER) = 0xDC + toLWJGL(GLFW.GLFW_KEY_MENU) = 0xDD + + def glfwToLWJGL(keyCode: Int): Int = if (keyCode >= 0 && keyCode < toLWJGL.size) toLWJGL(keyCode) else -1 + + def keyToChar(keyCode: Int): Char = { + if (keyCode == GLFW.GLFW_KEY_ESCAPE) '\u001B' + else if (keyCode == GLFW.GLFW_KEY_ENTER) '\r' + else if (keyCode == GLFW.GLFW_KEY_TAB) '\t' + else if (keyCode == GLFW.GLFW_KEY_BACKSPACE) '\b' + else if (keyCode == GLFW.GLFW_KEY_KP_ENTER) '\r' + else '\u0000' } } diff --git a/src/main/scala/li/cil/oc/client/gui/traits/LockedHotbar.scala b/src/main/scala/li/cil/oc/client/gui/traits/LockedHotbar.scala index 57c9a8c2e9..37eb9cc1fd 100644 --- a/src/main/scala/li/cil/oc/client/gui/traits/LockedHotbar.scala +++ b/src/main/scala/li/cil/oc/client/gui/traits/LockedHotbar.scala @@ -1,18 +1,17 @@ package li.cil.oc.client.gui.traits -import net.minecraft.client.gui.inventory.GuiContainer -import net.minecraft.inventory.ClickType -import net.minecraft.inventory.Slot +import net.minecraft.client.gui.screen.inventory.ContainerScreen +import net.minecraft.inventory.container.ClickType +import net.minecraft.inventory.container.Container +import net.minecraft.inventory.container.Slot import net.minecraft.item.ItemStack -trait LockedHotbar extends GuiContainer { +trait LockedHotbar[C <: Container] extends ContainerScreen[C] { def lockedStack: ItemStack - override def handleMouseClick(slot: Slot, slotId: Int, mouseButton: Int, clickType: ClickType): Unit = { - if (slot == null || !slot.getStack.isItemEqual(lockedStack)) { - super.handleMouseClick(slot, slotId, mouseButton, clickType) + override def slotClicked(slot: Slot, slotId: Int, mouseButton: Int, clickType: ClickType): Unit = { + if (slot == null || !slot.getItem.sameItem(lockedStack)) { + super.slotClicked(slot, slotId, mouseButton, clickType) } } - - protected override def checkHotbarKeys(keyCode: Int) = false } diff --git a/src/main/scala/li/cil/oc/client/gui/traits/Window.scala b/src/main/scala/li/cil/oc/client/gui/traits/Window.scala index 9ca7e0b09a..f3b3778a61 100644 --- a/src/main/scala/li/cil/oc/client/gui/traits/Window.scala +++ b/src/main/scala/li/cil/oc/client/gui/traits/Window.scala @@ -2,44 +2,40 @@ package li.cil.oc.client.gui.traits import java.util -import li.cil.oc.util.OldScaledResolution -import net.minecraft.client.gui.Gui -import net.minecraft.client.gui.GuiScreen -import net.minecraft.client.gui.ScaledResolution +import com.mojang.blaze3d.matrix.MatrixStack +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.AbstractGui +import net.minecraft.client.gui.screen.Screen import net.minecraft.util.ResourceLocation -trait Window extends GuiScreen { - var guiLeft = 0 - var guiTop = 0 - var xSize = 0 - var ySize = 0 +trait Window extends Screen { + var leftPos = 0 + var topPos = 0 + var imageWidth = 0 + var imageHeight = 0 val windowWidth = 176 val windowHeight = 166 def backgroundImage: ResourceLocation - protected def add[T](list: util.List[T], value: Any) = list.add(value.asInstanceOf[T]) + override def isPauseScreen = false - override def doesGuiPauseGame = false + override protected def init(): Unit = { + super.init() - override def initGui(): Unit = { - super.initGui() - - val screenSize = new ScaledResolution(mc) - val guiSize = new OldScaledResolution(mc, windowWidth, windowHeight) - val (midX, midY) = (screenSize.getScaledWidth / 2, screenSize.getScaledHeight / 2) - guiLeft = midX - guiSize.getScaledWidth / 2 - guiTop = midY - guiSize.getScaledHeight / 2 - xSize = guiSize.getScaledWidth - ySize = guiSize.getScaledHeight + imageWidth = windowWidth + imageHeight = windowHeight + leftPos = (width - imageWidth) / 2 + topPos = (height - imageHeight) / 2 } - override def drawScreen(mouseX: Int, mouseY: Int, dt: Float): Unit = { - mc.renderEngine.bindTexture(backgroundImage) - Gui.drawModalRectWithCustomSizedTexture(guiLeft, guiTop, 0, 0, xSize, ySize, windowWidth, windowHeight) + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int, dt: Float): Unit = { + Minecraft.getInstance.getTextureManager.bind(backgroundImage) + // Texture width and height are intentionally backwards. + AbstractGui.blit(stack, leftPos, topPos, getBlitOffset, 0, 0, imageWidth, imageHeight, windowHeight, windowWidth) - super.drawScreen(mouseX, mouseY, dt) + super.render(stack, mouseX, mouseY, dt) } } diff --git a/src/main/scala/li/cil/oc/client/gui/widget/ProgressBar.scala b/src/main/scala/li/cil/oc/client/gui/widget/ProgressBar.scala index beb5ef240a..a1abc50fbb 100644 --- a/src/main/scala/li/cil/oc/client/gui/widget/ProgressBar.scala +++ b/src/main/scala/li/cil/oc/client/gui/widget/ProgressBar.scala @@ -1,5 +1,6 @@ package li.cil.oc.client.gui.widget +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.client.Textures import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats @@ -14,25 +15,25 @@ class ProgressBar(val x: Int, val y: Int) extends Widget { var level = 0.0 - def draw() { + def draw(stack: MatrixStack) { if (level > 0) { val u0 = 0 - val u1 = level + val u1 = level.toFloat val v0 = 0 val v1 = 1 val tx = owner.windowX + x val ty = owner.windowY + y - val w = width * level + val w = (width * level).toFloat Textures.bind(barTexture) val t = Tessellator.getInstance - val r = t.getBuffer + val r = t.getBuilder r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(tx, ty, owner.windowZ).tex(u0, v0).endVertex() - r.pos(tx, ty + height, owner.windowZ).tex(u0, v1).endVertex() - r.pos(tx + w, ty + height, owner.windowZ).tex(u1, v1).endVertex() - r.pos(tx + w, ty, owner.windowZ).tex(u1, v0).endVertex() - t.draw() + r.vertex(stack.last.pose, tx, ty, owner.windowZ).uv(u0, v0).endVertex() + r.vertex(stack.last.pose, tx, ty + height, owner.windowZ).uv(u0, v1).endVertex() + r.vertex(stack.last.pose, tx + w, ty + height, owner.windowZ).uv(u1, v1).endVertex() + r.vertex(stack.last.pose, tx + w, ty, owner.windowZ).uv(u1, v0).endVertex() + t.end() } } } diff --git a/src/main/scala/li/cil/oc/client/gui/widget/Widget.scala b/src/main/scala/li/cil/oc/client/gui/widget/Widget.scala index db15521376..9c55386ddd 100644 --- a/src/main/scala/li/cil/oc/client/gui/widget/Widget.scala +++ b/src/main/scala/li/cil/oc/client/gui/widget/Widget.scala @@ -1,5 +1,8 @@ package li.cil.oc.client.gui.widget +import com.mojang.blaze3d.matrix.MatrixStack + +@Deprecated abstract class Widget { var owner: WidgetContainer = _ @@ -11,5 +14,5 @@ abstract class Widget { def height: Int - def draw(): Unit + def draw(stack: MatrixStack): Unit } diff --git a/src/main/scala/li/cil/oc/client/gui/widget/WidgetContainer.scala b/src/main/scala/li/cil/oc/client/gui/widget/WidgetContainer.scala index e94089dac4..6b476e2888 100644 --- a/src/main/scala/li/cil/oc/client/gui/widget/WidgetContainer.scala +++ b/src/main/scala/li/cil/oc/client/gui/widget/WidgetContainer.scala @@ -1,11 +1,14 @@ package li.cil.oc.client.gui.widget +import com.mojang.blaze3d.matrix.MatrixStack + import scala.collection.mutable +@Deprecated trait WidgetContainer { protected val widgets = mutable.ArrayBuffer.empty[Widget] - def addWidget[T <: Widget](widget: T) = { + def addCustomWidget[T <: Widget](widget: T) = { widgets += widget widget.owner = this widget @@ -17,7 +20,7 @@ trait WidgetContainer { def windowZ = 0f - def drawWidgets() { - widgets.foreach(_.draw()) + def drawWidgets(stack: MatrixStack) { + widgets.foreach(_.draw(stack)) } } diff --git a/src/main/scala/li/cil/oc/client/renderer/HighlightRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/HighlightRenderer.scala index 9af67f8e5e..743913a9cd 100644 --- a/src/main/scala/li/cil/oc/client/renderer/HighlightRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/HighlightRenderer.scala @@ -1,17 +1,18 @@ package li.cil.oc.client.renderer +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.client.Textures -import li.cil.oc.util.ExtendedAABB._ import li.cil.oc.util.ExtendedWorld._ -import li.cil.oc.util.{BlockPosition, RenderState} -import li.cil.oc.{Constants, Settings, api, common} +import li.cil.oc.util.BlockPosition +import li.cil.oc.{Constants, Settings, api} +import net.minecraft.client.Minecraft import net.minecraft.client.renderer._ import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.{RayTraceResult, Vec3d} -import net.minecraftforge.client.event.DrawBlockHighlightEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import org.lwjgl.opengl.GL11 +import net.minecraft.util.Direction +import net.minecraft.util.Hand +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraftforge.client.event.DrawHighlightEvent +import net.minecraftforge.eventbus.api.SubscribeEvent import scala.util.Random @@ -20,227 +21,70 @@ object HighlightRenderer { lazy val tablet = api.Items.get(Constants.ItemName.Tablet) + val TexHologram = RenderTypes.createTexturedQuad("hologram_effect", Textures.Model.HologramEffect, DefaultVertexFormats.POSITION_TEX_COLOR, true) + @SubscribeEvent - def onDrawBlockHighlight(e: DrawBlockHighlightEvent): Unit = if (e.getTarget != null && e.getTarget.getBlockPos != null) { + def onDrawBlockHighlight(e: DrawHighlightEvent.HighlightBlock): Unit = if (e.getTarget != null && e.getTarget.getBlockPos != null) { val hitInfo = e.getTarget - val world = e.getPlayer.getEntityWorld + val world = Minecraft.getInstance.level val blockPos = BlockPosition(hitInfo.getBlockPos, world) - if (hitInfo.typeOfHit == RayTraceResult.Type.BLOCK && api.Items.get(e.getPlayer.getHeldItemMainhand) == tablet) { + val stack = e.getMatrix + if (api.Items.get(Minecraft.getInstance.player.getItemInHand(Hand.MAIN_HAND)) == tablet) { val isAir = world.isAirBlock(blockPos) if (!isAir) { - val block = world.getBlock(blockPos) - val bounds = block.getSelectedBoundingBox(world.getBlockState(hitInfo.getBlockPos), world, hitInfo.getBlockPos).offset(-blockPos.x, -blockPos.y, -blockPos.z) - val sideHit = hitInfo.sideHit - val playerPos = new Vec3d( - e.getPlayer.prevPosX + (e.getPlayer.posX - e.getPlayer.prevPosX) * e.getPartialTicks, - e.getPlayer.prevPosY + (e.getPlayer.posY - e.getPlayer.prevPosY) * e.getPartialTicks, - e.getPlayer.prevPosZ + (e.getPlayer.posZ - e.getPlayer.prevPosZ) * e.getPartialTicks) - val renderPos = blockPos.offset(-playerPos.x, -playerPos.y, -playerPos.z) - - GlStateManager.pushMatrix() - RenderState.pushAttrib() - RenderState.makeItBlend() - Textures.bind(Textures.Model.HologramEffect) + val shape = world.getBlockState(hitInfo.getBlockPos).getShape(world, hitInfo.getBlockPos, ISelectionContext.of(e.getInfo.getEntity)) + val (minX, minY, minZ) = (shape.min(Direction.Axis.X).toFloat, shape.min(Direction.Axis.Y).toFloat, shape.min(Direction.Axis.Z).toFloat) + val (maxX, maxY, maxZ) = (shape.max(Direction.Axis.X).toFloat, shape.max(Direction.Axis.Y).toFloat, shape.max(Direction.Axis.Z).toFloat) + val sideHit = hitInfo.getDirection + val view = e.getInfo.getPosition - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) - GlStateManager.color(0.0F, 1.0F, 0.0F, 0.4F) + stack.pushPose() - GlStateManager.translate(renderPos.x, renderPos.y, renderPos.z) - GlStateManager.scale(1.002, 1.002, 1.002) + stack.translate(blockPos.x - view.x, blockPos.y - view.y, blockPos.z - view.z) + stack.scale(1.002f, 1.002f, 1.002f) if (Settings.get.hologramFlickerFrequency > 0 && random.nextDouble() < Settings.get.hologramFlickerFrequency) { - val (sx, sy, sz) = (1 - math.abs(sideHit.getFrontOffsetX), 1 - math.abs(sideHit.getFrontOffsetY), 1 - math.abs(sideHit.getFrontOffsetZ)) - GlStateManager.scale(1 + random.nextGaussian() * 0.01, 1 + random.nextGaussian() * 0.001, 1 + random.nextGaussian() * 0.01) - GlStateManager.translate(random.nextGaussian() * 0.01 * sx, random.nextGaussian() * 0.01 * sy, random.nextGaussian() * 0.01 * sz) + val (sx, sy, sz) = (1 - math.abs(sideHit.getStepX), 1 - math.abs(sideHit.getStepY), 1 - math.abs(sideHit.getStepZ)) + stack.scale(1f + (random.nextGaussian() * 0.01).toFloat, 1f + (random.nextGaussian() * 0.001).toFloat, 1f + (random.nextGaussian() * 0.01).toFloat) + stack.translate((random.nextGaussian() * 0.01 * sx).toFloat, (random.nextGaussian() * 0.01 * sy).toFloat, (random.nextGaussian() * 0.01 * sz).toFloat) } - val t = Tessellator.getInstance() - val r = t.getBuffer - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = e.getBuffers.getBuffer(TexHologram) sideHit match { - case EnumFacing.UP => - r.pos(bounds.maxX, bounds.maxY + 0.002, bounds.maxZ).tex(bounds.maxZ * 16, bounds.maxX * 16).endVertex() - r.pos(bounds.maxX, bounds.maxY + 0.002, bounds.minZ).tex(bounds.minZ * 16, bounds.maxX * 16).endVertex() - r.pos(bounds.minX, bounds.maxY + 0.002, bounds.minZ).tex(bounds.minZ * 16, bounds.minX * 16).endVertex() - r.pos(bounds.minX, bounds.maxY + 0.002, bounds.maxZ).tex(bounds.maxZ * 16, bounds.minX * 16).endVertex() - case EnumFacing.DOWN => - r.pos(bounds.maxX, bounds.minY - 0.002, bounds.minZ).tex(bounds.minZ * 16, bounds.maxX * 16).endVertex() - r.pos(bounds.maxX, bounds.minY - 0.002, bounds.maxZ).tex(bounds.maxZ * 16, bounds.maxX * 16).endVertex() - r.pos(bounds.minX, bounds.minY - 0.002, bounds.maxZ).tex(bounds.maxZ * 16, bounds.minX * 16).endVertex() - r.pos(bounds.minX, bounds.minY - 0.002, bounds.minZ).tex(bounds.minZ * 16, bounds.minX * 16).endVertex() - case EnumFacing.EAST => - r.pos(bounds.maxX + 0.002, bounds.maxY, bounds.minZ).tex(bounds.minZ * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.maxX + 0.002, bounds.maxY, bounds.maxZ).tex(bounds.maxZ * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.maxX + 0.002, bounds.minY, bounds.maxZ).tex(bounds.maxZ * 16, bounds.minY * 16).endVertex() - r.pos(bounds.maxX + 0.002, bounds.minY, bounds.minZ).tex(bounds.minZ * 16, bounds.minY * 16).endVertex() - case EnumFacing.WEST => - r.pos(bounds.minX - 0.002, bounds.maxY, bounds.maxZ).tex(bounds.maxZ * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.minX - 0.002, bounds.maxY, bounds.minZ).tex(bounds.minZ * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.minX - 0.002, bounds.minY, bounds.minZ).tex(bounds.minZ * 16, bounds.minY * 16).endVertex() - r.pos(bounds.minX - 0.002, bounds.minY, bounds.maxZ).tex(bounds.maxZ * 16, bounds.minY * 16).endVertex() - case EnumFacing.SOUTH => - r.pos(bounds.maxX, bounds.maxY, bounds.maxZ + 0.002).tex(bounds.maxX * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.minX, bounds.maxY, bounds.maxZ + 0.002).tex(bounds.minX * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.minX, bounds.minY, bounds.maxZ + 0.002).tex(bounds.minX * 16, bounds.minY * 16).endVertex() - r.pos(bounds.maxX, bounds.minY, bounds.maxZ + 0.002).tex(bounds.maxX * 16, bounds.minY * 16).endVertex() + case Direction.UP => + r.vertex(stack.last.pose, maxX, maxY + 0.002f, maxZ).uv(maxZ * 16, maxX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX, maxY + 0.002f, minZ).uv(minZ * 16, maxX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX, maxY + 0.002f, minZ).uv(minZ * 16, minX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX, maxY + 0.002f, maxZ).uv(maxZ * 16, minX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + case Direction.DOWN => + r.vertex(stack.last.pose, maxX, minY - 0.002f, minZ).uv(minZ * 16, maxX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX, minY - 0.002f, maxZ).uv(maxZ * 16, maxX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX, minY - 0.002f, maxZ).uv(maxZ * 16, minX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX, minY - 0.002f, minZ).uv(minZ * 16, minX * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + case Direction.EAST => + r.vertex(stack.last.pose, maxX + 0.002f, maxY, minZ).uv(minZ * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX + 0.002f, maxY, maxZ).uv(maxZ * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX + 0.002f, minY, maxZ).uv(maxZ * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX + 0.002f, minY, minZ).uv(minZ * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + case Direction.WEST => + r.vertex(stack.last.pose, minX - 0.002f, maxY, maxZ).uv(maxZ * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX - 0.002f, maxY, minZ).uv(minZ * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX - 0.002f, minY, minZ).uv(minZ * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX - 0.002f, minY, maxZ).uv(maxZ * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + case Direction.SOUTH => + r.vertex(stack.last.pose, maxX, maxY, maxZ + 0.002f).uv(maxX * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX, maxY, maxZ + 0.002f).uv(minX * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX, minY, maxZ + 0.002f).uv(minX * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX, minY, maxZ + 0.002f).uv(maxX * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() case _ => - r.pos(bounds.minX, bounds.maxY, bounds.minZ - 0.002).tex(bounds.minX * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.maxX, bounds.maxY, bounds.minZ - 0.002).tex(bounds.maxX * 16, bounds.maxY * 16).endVertex() - r.pos(bounds.maxX, bounds.minY, bounds.minZ - 0.002).tex(bounds.maxX * 16, bounds.minY * 16).endVertex() - r.pos(bounds.minX, bounds.minY, bounds.minZ - 0.002).tex(bounds.minX * 16, bounds.minY * 16).endVertex() + r.vertex(stack.last.pose, minX, maxY, minZ - 0.002f).uv(minX * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX, maxY, minZ - 0.002f).uv(maxX * 16, maxY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, maxX, minY, minZ - 0.002f).uv(maxX * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() + r.vertex(stack.last.pose, minX, minY, minZ - 0.002f).uv(minX * 16, minY * 16).color(0.0F, 1.0F, 0.0F, 0.4F).endVertex() } - t.draw() - RenderState.disableBlend() - RenderState.popAttrib() - GlStateManager.popMatrix() + stack.popPose() } } - - if (hitInfo.typeOfHit == RayTraceResult.Type.BLOCK) e.getPlayer.getEntityWorld.getTileEntity(hitInfo.getBlockPos) match { - case print: common.tileentity.Print if print.shapes.nonEmpty => - val pos = new Vec3d( - e.getPlayer.prevPosX + (e.getPlayer.posX - e.getPlayer.prevPosX) * e.getPartialTicks, - e.getPlayer.prevPosY + (e.getPlayer.posY - e.getPlayer.prevPosY) * e.getPartialTicks, - e.getPlayer.prevPosZ + (e.getPlayer.posZ - e.getPlayer.prevPosZ) * e.getPartialTicks) - val expansion = 0.002f - - // See RenderGlobal.drawSelectionBox. - GlStateManager.enableBlend() - OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 1) - GlStateManager.color(0, 0, 0, 0.4f) - GlStateManager.glLineWidth(2) - GlStateManager.disableTexture2D() - GlStateManager.depthMask(false) - - for (shape <- print.shapes) { - val bounds = shape.bounds.rotateTowards(print.facing) - RenderGlobal.drawSelectionBoundingBox(bounds.grow(expansion, expansion, expansion) - .offset(blockPos.x, blockPos.y, blockPos.z) - .offset(-pos.x, -pos.y, -pos.z), 0, 0, 0, 0x66/0xFFf.toFloat) - } - - GlStateManager.depthMask(true) - GlStateManager.enableTexture2D() - GlStateManager.disableBlend() - - e.setCanceled(true) - case cable: common.tileentity.Cable => - // See RenderGlobal.drawSelectionBox. - GlStateManager.enableBlend() - OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 1) - GlStateManager.color(0, 0, 0, 0.4f) - GlStateManager.glLineWidth(2) - GlStateManager.disableTexture2D() - GlStateManager.depthMask(false) - GlStateManager.pushMatrix() - - val player = e.getPlayer - GlStateManager.translate( - blockPos.x - (player.lastTickPosX + (player.posX - player.lastTickPosX) * e.getPartialTicks), - blockPos.y - (player.lastTickPosY + (player.posY - player.lastTickPosY) * e.getPartialTicks), - blockPos.z - (player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * e.getPartialTicks) - ) - - val mask = common.block.Cable.neighbors(world, hitInfo.getBlockPos) - val tesselator = Tessellator.getInstance - val buffer = tesselator.getBuffer - - buffer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION) - Cable.drawOverlay(buffer, mask) - tesselator.draw() - - GlStateManager.popMatrix() - GlStateManager.depthMask(true) - GlStateManager.enableTexture2D() - GlStateManager.disableBlend() - - e.setCanceled(true) - case _ => - } } - - private object Cable { - private final val EXPAND = 0.002f - private final val MIN = common.block.Cable.MIN - EXPAND - private final val MAX = common.block.Cable.MAX + EXPAND - - def drawOverlay(buffer: BufferBuilder, mask: Int): Unit = { - // Draw the cable arms - for (side <- EnumFacing.values) { - if (((1 << side.getIndex) & mask) != 0) { - val offset = if (side.getAxisDirection == EnumFacing.AxisDirection.NEGATIVE) -EXPAND else 1 + EXPAND - val centre = if (side.getAxisDirection == EnumFacing.AxisDirection.NEGATIVE) MIN else MAX - - // Draw the arm end quad - drawLineAdjacent(buffer, side.getAxis, offset, MIN, MIN, MIN, MAX) - drawLineAdjacent(buffer, side.getAxis, offset, MIN, MAX, MAX, MAX) - drawLineAdjacent(buffer, side.getAxis, offset, MAX, MAX, MAX, MIN) - drawLineAdjacent(buffer, side.getAxis, offset, MAX, MIN, MIN, MIN) - - // Draw the connecting lines to the middle - drawLineAlong(buffer, side.getAxis, MIN, MIN, offset, centre) - drawLineAlong(buffer, side.getAxis, MAX, MIN, offset, centre) - drawLineAlong(buffer, side.getAxis, MAX, MAX, offset, centre) - drawLineAlong(buffer, side.getAxis, MIN, MAX, offset, centre) - } - } - - // Draw the cable core - drawCore(buffer, mask, EnumFacing.WEST, EnumFacing.DOWN, EnumFacing.Axis.Z) - drawCore(buffer, mask, EnumFacing.WEST, EnumFacing.UP, EnumFacing.Axis.Z) - drawCore(buffer, mask, EnumFacing.EAST, EnumFacing.DOWN, EnumFacing.Axis.Z) - drawCore(buffer, mask, EnumFacing.EAST, EnumFacing.UP, EnumFacing.Axis.Z) - - drawCore(buffer, mask, EnumFacing.WEST, EnumFacing.NORTH, EnumFacing.Axis.Y) - drawCore(buffer, mask, EnumFacing.WEST, EnumFacing.SOUTH, EnumFacing.Axis.Y) - drawCore(buffer, mask, EnumFacing.EAST, EnumFacing.NORTH, EnumFacing.Axis.Y) - drawCore(buffer, mask, EnumFacing.EAST, EnumFacing.SOUTH, EnumFacing.Axis.Y) - - drawCore(buffer, mask, EnumFacing.DOWN, EnumFacing.NORTH, EnumFacing.Axis.X) - drawCore(buffer, mask, EnumFacing.DOWN, EnumFacing.SOUTH, EnumFacing.Axis.X) - drawCore(buffer, mask, EnumFacing.UP, EnumFacing.NORTH, EnumFacing.Axis.X) - drawCore(buffer, mask, EnumFacing.UP, EnumFacing.SOUTH, EnumFacing.Axis.X) - } - - /** Draw part of the core object */ - private def drawCore(buffer: BufferBuilder, mask: Int, a: EnumFacing, b: EnumFacing, other: EnumFacing.Axis): Unit = { - if (((mask >> a.ordinal) & 1) != ((mask >> b.ordinal) & 1)) return - - val offA = if (a.getAxisDirection == EnumFacing.AxisDirection.NEGATIVE) MIN else MAX - val offB = if (b.getAxisDirection == EnumFacing.AxisDirection.NEGATIVE) MIN else MAX - drawLineAlong(buffer, other, offA, offB, MIN, MAX) - } - - /** Draw a line parallel to an axis */ - private def drawLineAlong(buffer: BufferBuilder, axis: EnumFacing.Axis, offA: Double, offB: Double, start: Double, end: Double): Unit = { - axis match { - case EnumFacing.Axis.X => - buffer.pos(start, offA, offB).endVertex() - buffer.pos(end, offA, offB).endVertex() - case EnumFacing.Axis.Y => - buffer.pos(offA, start, offB).endVertex() - buffer.pos(offA, end, offB).endVertex() - case EnumFacing.Axis.Z => - buffer.pos(offA, offB, start).endVertex() - buffer.pos(offA, offB, end).endVertex() - } - } - - /** Draw a line perpendicular to an axis */ - private def drawLineAdjacent(buffer: BufferBuilder, axis: EnumFacing.Axis, offset: Double, startA: Double, startB: Double, endA: Double, endB: Double): Unit = { - axis match { - case EnumFacing.Axis.X => - buffer.pos(offset, startA, startB).endVertex() - buffer.pos(offset, endA, endB).endVertex() - case EnumFacing.Axis.Y => - buffer.pos(startA, offset, startB).endVertex() - buffer.pos(endA, offset, endB).endVertex() - case EnumFacing.Axis.Z => - buffer.pos(startA, startB, offset).endVertex() - buffer.pos(endA, endB, offset).endVertex() - } - } - } - } diff --git a/src/main/scala/li/cil/oc/client/renderer/MFUTargetRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/MFUTargetRenderer.scala index 91850577b5..dd7f6f150f 100644 --- a/src/main/scala/li/cil/oc/client/renderer/MFUTargetRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/MFUTargetRenderer.scala @@ -1,63 +1,60 @@ package li.cil.oc.client.renderer +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.util.BlockPosition import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.RenderType import net.minecraft.item.ItemStack +import net.minecraft.util.Hand +import net.minecraft.util.ResourceLocation +import net.minecraft.util.math.vector.Vector4f +import net.minecraft.util.math.vector.Matrix4f import net.minecraftforge.client.event.RenderWorldLastEvent import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import org.lwjgl.opengl.GL11 +import net.minecraftforge.eventbus.api.SubscribeEvent object MFUTargetRenderer { - private val color = 0x00FF00 + private val (drawRed, drawGreen, drawBlue) = (0.0f, 1.0f, 0.0f) + private lazy val mfu = api.Items.get(Constants.ItemName.MFU) @SubscribeEvent def onRenderWorldLastEvent(e: RenderWorldLastEvent) { - val mc = Minecraft.getMinecraft + val mc = Minecraft.getInstance val player = mc.player if (player == null) return - player.getHeldItemMainhand match { - case stack: ItemStack if api.Items.get(stack) == mfu && stack.hasTagCompound => - val data = stack.getTagCompound - if (data.hasKey(Settings.namespace + "coord", NBT.TAG_INT_ARRAY)) { - val Array(x, y, z, dimension, side) = data.getIntArray(Settings.namespace + "coord") - if (player.getEntityWorld.provider.getDimension != dimension) return - if (player.getDistance(x, y, z) > 64) return - - val bounds = BlockPosition(x, y, z).bounds.grow(0.1, 0.1, 0.1) + player.getItemInHand(Hand.MAIN_HAND) match { + case stack: ItemStack if api.Items.get(stack) == mfu && stack.hasTag => + val data = stack.getTag + if (data.contains(Settings.namespace + "coord", NBT.TAG_INT_ARRAY)) { + val dimension = new ResourceLocation(data.getString(Settings.namespace + "dimension")) + if (!player.level.dimension.location.equals(dimension)) return + val Array(x, y, z, side) = data.getIntArray(Settings.namespace + "coord") + if (player.distanceToSqr(x, y, z) > 64 * 64) return - val px = player.lastTickPosX + (player.posX - player.lastTickPosX) * e.getPartialTicks - val py = player.lastTickPosY + (player.posY - player.lastTickPosY) * e.getPartialTicks - val pz = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * e.getPartialTicks + val bounds = BlockPosition(x, y, z).bounds.inflate(0.1, 0.1, 0.1) RenderState.checkError(getClass.getName + ".onRenderWorldLastEvent: entering (aka: wasntme)") - GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) - GL11.glPushMatrix() - GL11.glTranslated(-px, -py, -pz) - RenderState.makeItBlend() - GL11.glDisable(GL11.GL_LIGHTING) - GL11.glDisable(GL11.GL_TEXTURE_2D) - GL11.glDisable(GL11.GL_DEPTH_TEST) - GL11.glDisable(GL11.GL_CULL_FACE) + val matrix = e.getMatrixStack + matrix.pushPose() + val camPos = Minecraft.getInstance.gameRenderer.getMainCamera.getPosition + matrix.translate(-camPos.x, -camPos.y, -camPos.z) - GL11.glColor4f( - ((color >> 16) & 0xFF) / 255f, - ((color >> 8) & 0xFF) / 255f, - ((color >> 0) & 0xFF) / 255f, - 0.25f) - GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE) - drawBox(bounds.minX, bounds.minY, bounds.minZ, bounds.maxX, bounds.maxY, bounds.maxZ) - GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL) - drawFace(bounds.minX, bounds.minY, bounds.minZ, bounds.maxX, bounds.maxY, bounds.maxZ, side) + RenderSystem.disableDepthTest() // Default state for depth test is disabled, but it's enabled here so we have to change it manually. + val buffer = Minecraft.getInstance.renderBuffers.bufferSource + drawBox(matrix.last.pose, buffer.getBuffer(RenderTypes.MFU_LINES), bounds.minX.toFloat, bounds.minY.toFloat, bounds.minZ.toFloat, + bounds.maxX.toFloat, bounds.maxY.toFloat, bounds.maxZ.toFloat, drawRed, drawGreen, drawBlue) + drawFace(matrix.last.pose, buffer.getBuffer(RenderTypes.MFU_QUADS), bounds.minX.toFloat, bounds.minY.toFloat, bounds.minZ.toFloat, + bounds.maxX.toFloat, bounds.maxY.toFloat, bounds.maxZ.toFloat, side, drawRed, drawGreen, drawBlue) + buffer.endBatch() - GL11.glPopMatrix() - GL11.glPopAttrib() + matrix.popPose() RenderState.checkError(getClass.getName + ".onRenderWorldLastEvent: leaving") } @@ -65,89 +62,70 @@ object MFUTargetRenderer { } } - private def drawBox(minX: Double, minY: Double, minZ: Double, maxX: Double, maxY: Double, maxZ: Double) { - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glEnd() - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glVertex3d(minX, maxY, minZ) - GL11.glEnd() - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glVertex3d(minX, maxY, minZ) - GL11.glEnd() - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glEnd() - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(minX, maxY, minZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glEnd() - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glEnd() + def drawBox(matrix: Matrix4f, builder: IVertexBuilder, minX: Float, minY: Float, minZ: Float, maxX: Float, maxY: Float, maxZ: Float, r: Float, g: Float, b: Float) { + // Bottom square. + builder.vertex(matrix, minX, minY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, minY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, minY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, minY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, minY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, minY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, minY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, minY, minZ).color(r, g, b, 0.5f).endVertex() + + // Vertical bars. + builder.vertex(matrix, minX, minY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, maxY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, minY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, maxY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, minY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, minY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, maxY, maxZ).color(r, g, b, 0.5f).endVertex() + + // Top square. + builder.vertex(matrix, maxX, maxY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, maxY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, maxY, maxZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, maxY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, minX, maxY, minZ).color(r, g, b, 0.5f).endVertex() + builder.vertex(matrix, maxX, maxY, minZ).color(r, g, b, 0.5f).endVertex() } - private def drawFace(minX: Double, minY: Double, minZ: Double, maxX: Double, maxY: Double, maxZ: Double, side: Int): Unit = { + private def drawFace(matrix: Matrix4f, builder: IVertexBuilder, minX: Float, minY: Float, minZ: Float, maxX: Float, maxY: Float, maxZ: Float, side: Int, r: Float, g: Float, b: Float): Unit = { side match { case 0 => // Down - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glEnd() + builder.vertex(matrix, minX, minY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, minY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, minY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, minY, minZ).color(r, g, b, 0.25f).endVertex() case 1 => // Up - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glVertex3d(minX, maxY, minZ) - GL11.glEnd() + builder.vertex(matrix, maxX, maxY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, maxY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, maxY, minZ).color(r, g, b, 0.25f).endVertex() case 2 => // North - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glVertex3d(minX, maxY, minZ) - GL11.glEnd() + builder.vertex(matrix, minX, minY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, minY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, maxY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, maxY, minZ).color(r, g, b, 0.25f).endVertex() case 3 => // South - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glEnd() + builder.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, minY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, minY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, maxY, maxZ).color(r, g, b, 0.25f).endVertex() case 4 => // East - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(minX, maxY, minZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glEnd() + builder.vertex(matrix, minX, minY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, maxY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, maxY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, minX, minY, maxZ).color(r, g, b, 0.25f).endVertex() case 5 => // West - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glEnd() + builder.vertex(matrix, maxX, minY, minZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, minY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, maxY, maxZ).color(r, g, b, 0.25f).endVertex() + builder.vertex(matrix, maxX, maxY, minZ).color(r, g, b, 0.25f).endVertex() case _ => // WTF? } } diff --git a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala index fb1d5b2eef..b062debe4d 100644 --- a/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala @@ -4,18 +4,22 @@ import java.util.concurrent.Callable import java.util.concurrent.TimeUnit import com.google.common.cache.CacheBuilder +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.api.event.RobotRenderEvent import li.cil.oc.client.renderer.tileentity.RobotRenderer import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher import net.minecraft.entity.Entity +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.util.math.vector.Vector3f import net.minecraftforge.client.event.RenderPlayerEvent -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent +import net.minecraftforge.eventbus.api.EventPriority +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.event.TickEvent.ClientTickEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object PetRenderer { @@ -35,7 +39,8 @@ object PetRenderer { "076541f1-f10a-46de-a127-dfab8adfbb75" ->(0.2, 1.0, 0.1), // vifino "e7e90198-0ccf-4662-a827-192ec8f4419d" ->(0.0, 0.2, 0.6), // Izaya "f514ee69-7bbb-4e46-9e94-d8176324cec2" ->(0.098, 0.471, 0.784), // Wobbo - "f812c043-78ba-4324-82ae-e8f05c52ae6e" ->(0.1, 0.8, 0.5) // payonel + "f812c043-78ba-4324-82ae-e8f05c52ae6e" ->(0.1, 0.8, 0.5), // payonel + "1db17ee7-8830-4bac-8018-de154340aae6" ->(0.0, 0.5, 1.0) // Kosmos ) private val petLocations = com.google.common.cache.CacheBuilder.newBuilder(). @@ -47,45 +52,36 @@ object PetRenderer { @SubscribeEvent def onPlayerRender(e: RenderPlayerEvent.Pre) { - val uuid = e.getEntityPlayer.getUniqueID.toString + val uuid = e.getPlayer.getUUID.toString if (hidden.contains(uuid) || !entitledPlayers.contains(uuid)) return rendering = Some(entitledPlayers(uuid)) - val worldTime = e.getEntityPlayer.getEntityWorld.getTotalWorldTime - val timeJitter = e.getEntityPlayer.hashCode ^ 0xFF + val worldTime = e.getPlayer.level.getGameTime + val timeJitter = e.getPlayer.hashCode ^ 0xFF val offset = timeJitter + worldTime / 20.0 val hover = (math.sin(timeJitter + (worldTime + e.getPartialRenderTick) / 20.0) * 0.03).toFloat - val location = petLocations.get(e.getEntityPlayer, new Callable[PetLocation] { - override def call() = new PetLocation(e.getEntityPlayer) + val location = petLocations.get(e.getPlayer, new Callable[PetLocation] { + override def call() = new PetLocation(e.getPlayer) }) - GlStateManager.pushMatrix() - RenderState.pushAttrib() - val localPos = Minecraft.getMinecraft.player.getPositionEyes(e.getPartialRenderTick) - val playerPos = e.getEntityPlayer.getPositionEyes(e.getPartialRenderTick) - val correction = 1.62 - (if (e.getEntityPlayer.isSneaking) 0.125 else 0) - GlStateManager.translate( - playerPos.x - localPos.x, - playerPos.y - localPos.y + correction, - playerPos.z - localPos.z) + val stack = e.getMatrixStack + stack.pushPose() + val self = Minecraft.getInstance.player + val other = e.getPlayer + val px = other.xOld + (other.getX - other.xOld) * e.getPartialRenderTick + val py = other.yOld + (other.getY - other.yOld) * e.getPartialRenderTick + other.getEyeHeight(other.getPose) + val pz = other.zOld + (other.getZ - other.zOld) * e.getPartialRenderTick + stack.translate(px - self.getX, py - self.getY, pz - self.getZ) - RenderState.enableEntityLighting() - GlStateManager.disableBlend() - GlStateManager.enableRescaleNormal() - GlStateManager.color(1, 1, 1, 1) + location.applyInterpolatedTransformations(stack, e.getPartialRenderTick) - location.applyInterpolatedTransformations(e.getPartialRenderTick) + stack.scale(0.3f, 0.3f, 0.3f) + stack.translate(0, hover, 0) - GlStateManager.scale(0.3f, 0.3f, 0.3f) - GlStateManager.translate(0, hover, 0) + RobotRenderer.renderChassis(stack, e.getBuffers, e.getLight, offset, isRunningOverride = true) - RobotRenderer.renderChassis(null, offset, isRunningOverride = true) - - GlStateManager.disableRescaleNormal() - - RenderState.popAttrib() - GlStateManager.popMatrix() + stack.popPose() rendering = None } @@ -93,7 +89,10 @@ object PetRenderer { @SubscribeEvent(priority = EventPriority.LOWEST) def onRobotRender(e: RobotRenderEvent) { rendering match { - case Some((r, g, b)) => GlStateManager.color(r.toFloat, g.toFloat, b.toFloat) + case Some((r, g, b)) => { + e.setLightColor(r.toFloat, g.toFloat, b.toFloat) + e.multiplyColors(r.toFloat, g.toFloat, b.toFloat) + } case _ => } } @@ -102,7 +101,7 @@ object PetRenderer { var x = 0.0 var y = 0.0 var z = 0.0 - var yaw = owner.rotationYaw + var yaw = owner.yRot var lastX = x var lastY = y @@ -110,10 +109,10 @@ object PetRenderer { var lastYaw = yaw def update() { - val dx = owner.lastTickPosX - owner.posX - val dy = owner.lastTickPosY - owner.posY - val dz = owner.lastTickPosZ - owner.posZ - val dYaw = owner.rotationYaw - yaw + val dx = owner.xOld - owner.getX + val dy = owner.yOld - owner.getY + val dz = owner.zOld - owner.getZ + val dYaw = owner.yRot - yaw lastX = x lastY = y lastZ = z @@ -127,23 +126,23 @@ object PetRenderer { yaw += dYaw * 0.2f } - def applyInterpolatedTransformations(dt: Float) { + def applyInterpolatedTransformations(stack: MatrixStack, dt: Float) { val ix = lastX + (x - lastX) * dt val iy = lastY + (y - lastY) * dt val iz = lastZ + (z - lastZ) * dt val iYaw = lastYaw + (yaw - lastYaw) * dt - GlStateManager.translate(ix, iy, iz) + stack.translate(ix, iy, iz) if (!isForInventory) { - GlStateManager.rotate(-iYaw, 0, 1, 0) + stack.mulPose(Vector3f.YP.rotationDegrees(-iYaw)) } else { - GlStateManager.rotate(-owner.rotationYaw, 0, 1, 0) + stack.mulPose(Vector3f.YP.rotationDegrees(-owner.yRot)) } - GlStateManager.translate(0.3, -0.1, -0.2) + stack.translate(0.3, -0.1, -0.2) } - private def isForInventory = Minecraft.getMinecraft.currentScreen != null && owner == Minecraft.getMinecraft.player + private def isForInventory = Minecraft.getInstance.screen != null && owner == Minecraft.getInstance.player } @SubscribeEvent diff --git a/src/main/scala/li/cil/oc/client/renderer/RenderCache.java b/src/main/scala/li/cil/oc/client/renderer/RenderCache.java new file mode 100644 index 0000000000..435384e36f --- /dev/null +++ b/src/main/scala/li/cil/oc/client/renderer/RenderCache.java @@ -0,0 +1,113 @@ +package li.cil.oc.client.renderer +; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import com.mojang.datafixers.util.Pair; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.BufferBuilder.DrawState; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.Tessellator; +import org.lwjgl.system.MemoryUtil; + +public class RenderCache implements IRenderTypeBuffer { + public static class DrawEntry { + private final RenderType type; + private final DrawState state; + private final ByteBuffer data; + + public DrawEntry(RenderType type, DrawState state, ByteBuffer data, boolean copy) { + this.type = type; + this.state = state; + if (copy) + { + int bufferCap = state.format().getVertexSize() * state.vertexCount(); + ByteBuffer temp = GLAllocation.createByteBuffer(bufferCap); + temp.put(data).flip(); + data = temp; + } + this.data = data; + } + + public RenderType type() { + return type; + } + + public DrawState state() { + return state; + } + + public ByteBuffer data() { + return data; + } + } + + private final List cached; + private RenderType activeType; + private BufferBuilder activeBuilder; + + public RenderCache() { + cached = new ArrayList<>(); + } + + public boolean isEmpty() { + return cached.isEmpty(); + } + + public void clear() { + cached.clear(); + } + + private void flush(RenderType type) { + if (type == activeType) { + activeBuilder.end(); + Pair rendered = activeBuilder.popNextBuffer(); + if (rendered.getSecond().hasRemaining()) { + cached.add(new DrawEntry(type, rendered.getFirst(), rendered.getSecond(), true)); + } + activeType = null; + } + } + + @Override + public IVertexBuilder getBuffer(RenderType type) { + if (type == null) throw new NullPointerException(); // Same as vanilla. + if (activeType != null) { + if (activeType == type) return activeBuilder; + flush(activeType); + } + activeType = type; + activeBuilder = Tessellator.getInstance().getBuilder(); + activeBuilder.clear(); + activeBuilder.begin(type.mode(), type.format()); + return activeBuilder; + } + + public void finish() { + // Flush the last active type (if any) so it gets rendered too. + if (activeType != null) flush(activeType); + } + + public void render(MatrixStack stack) { + // Apply transform globally so we don't have to update stored vertices. + RenderSystem.pushMatrix(); + RenderSystem.multMatrix(stack.last().pose()); + + cached.forEach(frame -> { + frame.type().setupRenderState(); + DrawState state = frame.state(); + state.format().setupBufferState(MemoryUtil.memAddress(frame.data())); + RenderSystem.drawArrays(state.mode(), 0, state.vertexCount()); + state.format().clearBufferState(); + frame.type().clearRenderState(); + }); + + RenderSystem.popMatrix(); + } +} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/client/renderer/RenderTypes.java b/src/main/scala/li/cil/oc/client/renderer/RenderTypes.java new file mode 100644 index 0000000000..2817d7ff77 --- /dev/null +++ b/src/main/scala/li/cil/oc/client/renderer/RenderTypes.java @@ -0,0 +1,152 @@ +package li.cil.oc.client.renderer; + +import java.util.OptionalDouble; + +import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.platform.GlStateManager; +import li.cil.oc.OpenComputers; +import li.cil.oc.client.Textures; +import net.minecraft.client.renderer.RenderState.LineState; +import net.minecraft.client.renderer.RenderState.TextureState; +import net.minecraft.client.renderer.RenderState.TexturingState; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.RenderType.State; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.client.renderer.vertex.VertexFormatElement; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +public class RenderTypes extends RenderType { + public static final VertexFormat POSITION_TEX_NORMAL = new VertexFormat(new ImmutableList.Builder() + .add(DefaultVertexFormats.ELEMENT_POSITION) + .add(DefaultVertexFormats.ELEMENT_UV0) + .add(DefaultVertexFormats.ELEMENT_NORMAL) + .add(DefaultVertexFormats.ELEMENT_PADDING) + .build()); + + public static final TextureState ROBOT_CHASSIS_TEXTURE = new TextureState(Textures.Model$.MODULE$.Robot(), false, false); + + public static final RenderType ROBOT_CHASSIS = create(OpenComputers.ID() + ":robot_chassis", + DefaultVertexFormats.BLOCK, GL11.GL_TRIANGLES, 1024, State.builder() + .setTextureState(ROBOT_CHASSIS_TEXTURE) + .setDiffuseLightingState(DIFFUSE_LIGHTING) + .setLightmapState(LIGHTMAP) + .createCompositeState(true)); + + public static final RenderType ROBOT_LIGHT = create(OpenComputers.ID() + ":robot_light", + DefaultVertexFormats.POSITION_COLOR_TEX, GL11.GL_QUADS, 256, State.builder() + .setTextureState(ROBOT_CHASSIS_TEXTURE) + .setTransparencyState(LIGHTNING_TRANSPARENCY) + .createCompositeState(true)); + + private static final RenderType createUpgrade(String name, ResourceLocation texture) { + return create(OpenComputers.ID() + ":upgrade_" + name, + POSITION_TEX_NORMAL, GL11.GL_QUADS, 1024, State.builder() + .setTextureState(new TextureState(texture, false, false)) + .createCompositeState(true)); + } + + public static final RenderType UPGRADE_CRAFTING = createUpgrade("crafting", Textures.Model$.MODULE$.UpgradeCrafting()); + + public static final RenderType UPGRADE_GENERATOR = createUpgrade("generator", Textures.Model$.MODULE$.UpgradeGenerator()); + + public static final RenderType UPGRADE_INVENTORY = createUpgrade("inventory", Textures.Model$.MODULE$.UpgradeInventory()); + + public static final RenderType MFU_LINES = create(OpenComputers.ID() + ":mfu_lines", + DefaultVertexFormats.POSITION_COLOR, GL11.GL_LINES, 1024, State.builder() + .setTransparencyState(TRANSLUCENT_TRANSPARENCY) + .setDepthTestState(NO_DEPTH_TEST) + .setOutputState(TRANSLUCENT_TARGET) + .setLineState(new LineState(OptionalDouble.of(2.0))) + .createCompositeState(false)); + + public static final RenderType MFU_QUADS = create(OpenComputers.ID() + ":mfu_quads", + DefaultVertexFormats.POSITION_COLOR, GL11.GL_QUADS, 256, State.builder() + .setTransparencyState(TRANSLUCENT_TRANSPARENCY) + .setDepthTestState(NO_DEPTH_TEST) + .setCullState(NO_CULL) + .setOutputState(TRANSLUCENT_TARGET) + .setWriteMaskState(COLOR_WRITE) + .createCompositeState(false)); + + public static final RenderType BLOCK_OVERLAY = create(OpenComputers.ID() + ":overlay_block", + DefaultVertexFormats.POSITION_TEX, GL11.GL_QUADS, 1024, State.builder() + .setTextureState(BLOCK_SHEET_MIPPED) + .setTransparencyState(LIGHTNING_TRANSPARENCY) + .setAlphaState(DEFAULT_ALPHA) + .createCompositeState(false)); + + public static final RenderType BLOCK_OVERLAY_COLOR = create(OpenComputers.ID() + ":overlay_block", + DefaultVertexFormats.POSITION_COLOR_TEX, GL11.GL_QUADS, 1024, State.builder() + .setTextureState(BLOCK_SHEET_MIPPED) + .setTransparencyState(LIGHTNING_TRANSPARENCY) + .setAlphaState(DEFAULT_ALPHA) + .createCompositeState(false)); + + public static final RenderType FONT_QUAD = create(OpenComputers.ID() + ":font_quad", + DefaultVertexFormats.POSITION_COLOR, GL11.GL_QUADS, 1024, State.builder() + .setWriteMaskState(COLOR_WRITE) + .createCompositeState(false)); + + private static class CustomTextureState extends TexturingState { + public CustomTextureState(int id) { + super("custom_tex_" + id, () -> { + // Should already be enabled, but vanilla does it too. + RenderSystem.enableTexture(); + RenderSystem.bindTexture(id); + }, () -> {}); + } + } + + private static class LinearTexturingState extends TexturingState { + public LinearTexturingState(boolean linear) { + super(linear ? "lin_font_texturing" : "near_font_texturing", () -> { + // Texture is already bound, only have to make set minify filter. + if (linear) GlStateManager._texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); + else GlStateManager._texParameter(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); + }, () -> { + // Nothing to do, the texture was already unbound. + }); + } + } + + private static final LinearTexturingState NEAR = new LinearTexturingState(false); + private static final LinearTexturingState LINEAR = new LinearTexturingState(true); + + public static final RenderType createFontTex(String name, ResourceLocation texture, boolean linear) { + return create(OpenComputers.ID() + ":font_stat_" + name, + DefaultVertexFormats.POSITION_COLOR_TEX, GL11.GL_QUADS, 1024, State.builder() + // First parameter is blur (i.e. linear filter). + // We can't use it because it's also MAG_FILTER. + .setTextureState(new TextureState(texture, false, false)) + .setTransparencyState(TRANSLUCENT_TRANSPARENCY) + .setAlphaState(DEFAULT_ALPHA) + .setTexturingState(linear ? LINEAR : NEAR) + .createCompositeState(false)); + } + + public static final RenderType createFontTex(int id) { + return create(OpenComputers.ID() + ":font_dyn_" + id, + DefaultVertexFormats.POSITION_COLOR_TEX, GL11.GL_QUADS, 1024, State.builder() + .setTexturingState(new CustomTextureState(id)) + .setTransparencyState(TRANSLUCENT_TRANSPARENCY) + .setAlphaState(DEFAULT_ALPHA) + .createCompositeState(false)); + } + + public static final RenderType createTexturedQuad(String name, ResourceLocation texture, VertexFormat format, boolean additive) { + return create(OpenComputers.ID() + ":tex_quad_" + name, + format, GL11.GL_QUADS, 1024, State.builder() + .setTextureState(new TextureState(texture, false, false)) + .setTransparencyState(additive ? LIGHTNING_TRANSPARENCY : TRANSLUCENT_TRANSPARENCY) + .setAlphaState(DEFAULT_ALPHA) + .createCompositeState(false)); + } + + private RenderTypes() { + super(null, null, 0, 0, false, false, null, null); + throw new Error(); + } +} diff --git a/src/main/scala/li/cil/oc/client/renderer/TextBufferRenderCache.scala b/src/main/scala/li/cil/oc/client/renderer/TextBufferRenderCache.scala index e025e22283..9843f3bade 100644 --- a/src/main/scala/li/cil/oc/client/renderer/TextBufferRenderCache.scala +++ b/src/main/scala/li/cil/oc/client/renderer/TextBufferRenderCache.scala @@ -1,113 +1,49 @@ package li.cil.oc.client.renderer -import java.util.concurrent.Callable import java.util.concurrent.TimeUnit import com.google.common.cache.CacheBuilder -import com.google.common.cache.RemovalListener -import com.google.common.cache.RemovalNotification +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.Settings import li.cil.oc.client.renderer.font.TextBufferRenderData import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GLAllocation -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.tileentity.TileEntity -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent -import org.lwjgl.opengl.GL11 +import net.minecraftforge.event.TickEvent.ClientTickEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -object TextBufferRenderCache extends Callable[Int] with RemovalListener[TileEntity, Int] { +object TextBufferRenderCache { val renderer = if (Settings.get.fontRenderer == "texture") new font.StaticFontRenderer() else new font.DynamicFontRenderer() private val cache = com.google.common.cache.CacheBuilder.newBuilder(). expireAfterAccess(2, TimeUnit.SECONDS). - removalListener(this). - asInstanceOf[CacheBuilder[TextBufferRenderData, Int]]. - build[TextBufferRenderData, Int]() - - // To allow access in cache entry init. - private var currentBuffer: TextBufferRenderData = _ + build[TextBufferRenderData, RenderCache]() // ----------------------------------------------------------------------- // // Rendering // ----------------------------------------------------------------------- // - def render(buffer: TextBufferRenderData) { - currentBuffer = buffer - compileOrDraw(cache.get(currentBuffer, this)) - } - - private def compileOrDraw(list: Int) = { - if (currentBuffer.dirty) { - RenderState.checkError(getClass.getName + ".compileOrDraw: entering (aka: wasntme)") + def render(stack: MatrixStack, buffer: TextBufferRenderData) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - for (line <- currentBuffer.data.buffer) { + val cached = cache.get(buffer, () => new RenderCache) + if (buffer.dirty || cached.isEmpty) { + for (line <- buffer.data.buffer) { renderer.generateChars(line) } - val doCompile = !RenderState.compilingDisplayList - if (doCompile) { - currentBuffer.dirty = false - GL11.glNewList(list, GL11.GL_COMPILE_AND_EXECUTE) - - RenderState.checkError(getClass.getName + ".compileOrDraw: glNewList") - } - - renderer.drawBuffer(currentBuffer.data, currentBuffer.viewport._1, currentBuffer.viewport._2) - - RenderState.checkError(getClass.getName + ".compileOrDraw: drawString") - - if (doCompile) { - GL11.glEndList() - - RenderState.checkError(getClass.getName + ".compileOrDraw: glEndList") - } - - RenderState.checkError(getClass.getName + ".compileOrDraw: leaving") - - true - } - else { - GL11.glCallList(list) - GlStateManager.enableTexture2D() - GlStateManager.depthMask(true) - GlStateManager.color(1, 1, 1, 1) - - // Because display lists and the GlStateManager don't like each other, apparently. - GL11.glEnable(GL11.GL_TEXTURE_2D) - RenderState.bindTexture(0) - GL11.glDepthMask(true) - GL11.glColor4f(1, 1, 1, 1) + buffer.dirty = false - RenderState.disableBlend() + cached.clear() + renderer.drawBuffer(new MatrixStack(), cached, buffer.data, buffer.viewport._1, buffer.viewport._2) + cached.finish() - RenderState.checkError(getClass.getName + ".compileOrDraw: glCallList") + RenderState.checkError(getClass.getName + ".render: compiled buffer") } - } - - // ----------------------------------------------------------------------- // - // Cache - // ----------------------------------------------------------------------- // - - def call = { - RenderState.checkError(getClass.getName + ".call: entering (aka: wasntme)") - - val list = GLAllocation.generateDisplayLists(1) - currentBuffer.dirty = true // Force compilation. - - RenderState.checkError(getClass.getName + ".call: leaving") - - list - } - - def onRemoval(e: RemovalNotification[TileEntity, Int]) { - RenderState.checkError(getClass.getName + ".onRemoval: entering (aka: wasntme)") - GLAllocation.deleteDisplayLists(e.getValue) + cached.render(stack) - RenderState.checkError(getClass.getName + ".onRemoval: leaving") + RenderState.checkError(getClass.getName + ".render: leaving") } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/client/renderer/WirelessNetworkDebugRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/WirelessNetworkDebugRenderer.scala index a0968c505e..21a653c1d6 100644 --- a/src/main/scala/li/cil/oc/client/renderer/WirelessNetworkDebugRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/WirelessNetworkDebugRenderer.scala @@ -1,14 +1,15 @@ package li.cil.oc.client.renderer +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Settings import li.cil.oc.server.network.WirelessNetwork import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.util.math.vector.Vector4f +import net.minecraft.util.math.vector.Matrix4f import net.minecraft.world.World import net.minecraftforge.client.event.RenderWorldLastEvent -import net.minecraftforge.fml.common.ObfuscationReflectionHelper -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent import org.lwjgl.opengl.GL11 object WirelessNetworkDebugRenderer { @@ -19,63 +20,70 @@ object WirelessNetworkDebugRenderer { if (Settings.rTreeDebugRenderer) { RenderState.checkError(getClass.getName + ".onRenderWorldLastEvent: entering (aka: wasntme)") - val world = ObfuscationReflectionHelper.getPrivateValue(classOf[net.minecraft.client.renderer.RenderGlobal], e.getContext, "theWorld", "field_72769_h", "r").asInstanceOf[World] - WirelessNetwork.dimensions.get(world.provider.getDimension) match { + val world = Minecraft.getInstance.level + WirelessNetwork.dimensions.get(world.dimension) match { case Some(tree) => - val mc = Minecraft.getMinecraft - val player = mc.player - val px = player.lastTickPosX + (player.posX - player.lastTickPosX) * e.getPartialTicks - val py = player.lastTickPosY + (player.posY - player.lastTickPosY) * e.getPartialTicks - val pz = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * e.getPartialTicks + val player = Minecraft.getInstance.player + val px = player.xOld + (player.getX - player.xOld) * e.getPartialTicks + val py = player.yOld + (player.getY - player.yOld) * e.getPartialTicks + val pz = player.zOld + (player.getZ - player.zOld) * e.getPartialTicks + val stack = e.getMatrixStack RenderState.pushAttrib() - GlStateManager.pushMatrix() - GL11.glTranslated(-px, -py, -pz) + stack.pushPose() + stack.translate(-px, -py, -pz) RenderState.makeItBlend() GL11.glDisable(GL11.GL_LIGHTING) GL11.glDisable(GL11.GL_TEXTURE_2D) GL11.glDisable(GL11.GL_DEPTH_TEST) GL11.glDisable(GL11.GL_CULL_FACE) - def drawBox(minX: Double, minY: Double, minZ: Double, maxX: Double, maxY: Double, maxZ: Double) { + def glVertex(matrix: Matrix4f, temp: Vector4f, x: Float, y: Float, z: Float) { + temp.set(x, y, z, 1) + temp.transform(matrix) + GL11.glVertex3f(temp.x, temp.y, temp.z) + } + + def drawBox(matrix: Matrix4f, temp: Vector4f, minX: Float, minY: Float, minZ: Float, maxX: Float, maxY: Float, maxZ: Float) { GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(maxX, minY, minZ) + glVertex(matrix, temp, minX, minY, minZ) + glVertex(matrix, temp, minX, minY, maxZ) + glVertex(matrix, temp, maxX, minY, maxZ) + glVertex(matrix, temp, maxX, minY, minZ) GL11.glEnd() GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glVertex3d(minX, maxY, minZ) + glVertex(matrix, temp, minX, minY, minZ) + glVertex(matrix, temp, maxX, minY, minZ) + glVertex(matrix, temp, maxX, maxY, minZ) + glVertex(matrix, temp, minX, maxY, minZ) GL11.glEnd() GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, maxY, minZ) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glVertex3d(minX, maxY, minZ) + glVertex(matrix, temp, maxX, maxY, minZ) + glVertex(matrix, temp, maxX, maxY, maxZ) + glVertex(matrix, temp, minX, maxY, maxZ) + glVertex(matrix, temp, minX, maxY, minZ) GL11.glEnd() GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(minX, minY, maxZ) - GL11.glVertex3d(minX, maxY, maxZ) + glVertex(matrix, temp, maxX, maxY, maxZ) + glVertex(matrix, temp, maxX, minY, maxZ) + glVertex(matrix, temp, minX, minY, maxZ) + glVertex(matrix, temp, minX, maxY, maxZ) GL11.glEnd() GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(minX, minY, minZ) - GL11.glVertex3d(minX, maxY, minZ) - GL11.glVertex3d(minX, maxY, maxZ) - GL11.glVertex3d(minX, minY, maxZ) + glVertex(matrix, temp, minX, minY, minZ) + glVertex(matrix, temp, minX, maxY, minZ) + glVertex(matrix, temp, minX, maxY, maxZ) + glVertex(matrix, temp, minX, minY, maxZ) GL11.glEnd() GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex3d(maxX, minY, minZ) - GL11.glVertex3d(maxX, minY, maxZ) - GL11.glVertex3d(maxX, maxY, maxZ) - GL11.glVertex3d(maxX, maxY, minZ) + glVertex(matrix, temp, maxX, minY, minZ) + glVertex(matrix, temp, maxX, minY, maxZ) + glVertex(matrix, temp, maxX, maxY, maxZ) + glVertex(matrix, temp, maxX, maxY, minZ) GL11.glEnd() } + val temp = new Vector4f() GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE) for (((min, max), level) <- tree.allBounds) { val (minX, minY, minZ) = min @@ -86,13 +94,13 @@ object WirelessNetworkDebugRenderer { ((color >> 8) & 0xFF) / 255f, ((color >> 0) & 0xFF) / 255f, 0.25f) - val size = 0.5 - level * 0.05 - drawBox(minX - size, minY - size, minZ - size, maxX + size, maxY + size, maxZ + size) + val size = 0.5f - level * 0.05f + drawBox(stack.last.pose, temp, minX.toFloat - size, minY.toFloat - size, minZ.toFloat - size, maxX.toFloat + size, maxY.toFloat + size, maxZ.toFloat + size) } GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL) RenderState.popAttrib() - GlStateManager.popMatrix() + stack.popPose() case _ => } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala index a84053bd0d..d8fa5d5684 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala @@ -4,120 +4,110 @@ import java.util import java.util.Collections import li.cil.oc.client.Textures -import li.cil.oc.common.block +import li.cil.oc.common.block.property.PropertyCableConnection import li.cil.oc.common.tileentity -import li.cil.oc.integration.Mods -import li.cil.oc.util.BlockPosition import li.cil.oc.util.Color import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.ItemColorizer -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.model.BakedQuad -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ItemOverrideList -import net.minecraft.entity.EntityLivingBase -import net.minecraft.item.EnumDyeColor +import net.minecraft.block.BlockState +import net.minecraft.client.renderer.model.BakedQuad +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.client.world.ClientWorld +import net.minecraft.entity.LivingEntity +import net.minecraft.item.DyeColor import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.Vec3d -import net.minecraft.world.World -import net.minecraftforge.common.property.IExtendedBlockState +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3d +import net.minecraftforge.client.model.data.IModelData -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.bufferAsJavaList +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable -object CableModel extends CableModel - -class CableModel extends SmartBlockModelBase { +object CableModel extends SmartBlockModelBase { override def getOverrides: ItemOverrideList = ItemOverride - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = - state match { - case extended: IExtendedBlockState => - val neighbors = extended.getValue(block.Cable.NeighborsProp) - val color = extended.getValue(block.Cable.ColorProp) - val isCableSide = extended.getValue(block.Cable.IsSideCableProp) - (neighbors,color,isCableSide) match { - case (neighbourMask: Integer, color: Integer, isCableOnSideMask: Integer) => - val faces = mutable.ArrayBuffer.empty[BakedQuad] - - faces ++= bakeQuads(Middle, cableTexture, color) - for (side <- EnumFacing.values) { - val connected = (neighbourMask & (1 << side.getIndex)) != 0 - val isCableOnSide = (isCableOnSideMask & (1 << side.getIndex)) != 0 - val (plug, shortBody, longBody) = Connected(side.getIndex) - if (connected) { - if (isCableOnSide) { - faces ++= bakeQuads(longBody, cableTexture, color) - } - else { - faces ++= bakeQuads(shortBody, cableTexture, color) - faces ++= bakeQuads(plug, cableCapTexture, None) - } - } - else if (((1 << side.getOpposite.getIndex) & neighbourMask) == neighbourMask || neighbourMask == 0) { - faces ++= bakeQuads(Disconnected(side.getIndex), cableCapTexture, None) - } - } + override def getQuads(state: BlockState, side: Direction, rand: util.Random, data: IModelData): util.List[BakedQuad] = { + data match { + case cable: tileentity.Cable if side == null => + val color = cable.getColor + val faces = mutable.ArrayBuffer.empty[BakedQuad] - bufferAsJavaList(faces) - case _ => super.getQuads(state, side, rand) + faces ++= bakeQuads(Middle, cableTexture, color) + val directions = Direction.values + val numConnected = directions.count(d => state.getValue(PropertyCableConnection.BY_DIRECTION.get(d)) != PropertyCableConnection.Shape.NONE) + for (side <- directions) { + val shape = state.getValue(PropertyCableConnection.BY_DIRECTION.get(side)) + val connected = shape != PropertyCableConnection.Shape.NONE + val isCableOnSide = shape == PropertyCableConnection.Shape.CABLE + val (plug, shortBody, longBody) = Connected(side.get3DDataValue) + if (connected) { + if (isCableOnSide) { + faces ++= bakeQuads(longBody, cableTexture, color) + } + else { + faces ++= bakeQuads(shortBody, cableTexture, color) + faces ++= bakeQuads(plug, cableCapTexture, None) + } + } + else { + val otherConn = state.getValue(PropertyCableConnection.BY_DIRECTION.get(side.getOpposite)) != PropertyCableConnection.Shape.NONE + if ((otherConn && numConnected == 1) || numConnected == 0) { + faces ++= bakeQuads(Disconnected(side.get3DDataValue), cableCapTexture, None) + } + } } - case _ => super.getQuads(state, side, rand) - } - protected def isCable(pos: BlockPosition) = { - pos.world match { - case Some(world) => - world.getTileEntity(pos).isInstanceOf[tileentity.Cable] - case _ => false + bufferAsJavaList(faces) + case _ => super.getQuads(state, side, rand) } } - protected final val Middle = makeBox(new Vec3d(6 / 16f, 6 / 16f, 6 / 16f), new Vec3d(10 / 16f, 10 / 16f, 10 / 16f)) + protected final val Middle = makeBox(new Vector3d(6 / 16f, 6 / 16f, 6 / 16f), new Vector3d(10 / 16f, 10 / 16f, 10 / 16f)) // Per side, always plug + short cable + long cable (no plug). protected final val Connected = Array( - (makeBox(new Vec3d(5 / 16f, 0 / 16f, 5 / 16f), new Vec3d(11 / 16f, 1 / 16f, 11 / 16f)), - makeBox(new Vec3d(6 / 16f, 1 / 16f, 6 / 16f), new Vec3d(10 / 16f, 6 / 16f, 10 / 16f)), - makeBox(new Vec3d(6 / 16f, 0 / 16f, 6 / 16f), new Vec3d(10 / 16f, 6 / 16f, 10 / 16f))), - (makeBox(new Vec3d(5 / 16f, 15 / 16f, 5 / 16f), new Vec3d(11 / 16f, 16 / 16f, 11 / 16f)), - makeBox(new Vec3d(6 / 16f, 10 / 16f, 6 / 16f), new Vec3d(10 / 16f, 15 / 16f, 10 / 16f)), - makeBox(new Vec3d(6 / 16f, 10 / 16f, 6 / 16f), new Vec3d(10 / 16f, 16 / 16f, 10 / 16f))), - (makeBox(new Vec3d(5 / 16f, 5 / 16f, 0 / 16f), new Vec3d(11 / 16f, 11 / 16f, 1 / 16f)), - makeBox(new Vec3d(6 / 16f, 6 / 16f, 1 / 16f), new Vec3d(10 / 16f, 10 / 16f, 6 / 16f)), - makeBox(new Vec3d(6 / 16f, 6 / 16f, 0 / 16f), new Vec3d(10 / 16f, 10 / 16f, 6 / 16f))), - (makeBox(new Vec3d(5 / 16f, 5 / 16f, 15 / 16f), new Vec3d(11 / 16f, 11 / 16f, 16 / 16f)), - makeBox(new Vec3d(6 / 16f, 6 / 16f, 10 / 16f), new Vec3d(10 / 16f, 10 / 16f, 15 / 16f)), - makeBox(new Vec3d(6 / 16f, 6 / 16f, 10 / 16f), new Vec3d(10 / 16f, 10 / 16f, 16 / 16f))), - (makeBox(new Vec3d(0 / 16f, 5 / 16f, 5 / 16f), new Vec3d(1 / 16f, 11 / 16f, 11 / 16f)), - makeBox(new Vec3d(1 / 16f, 6 / 16f, 6 / 16f), new Vec3d(6 / 16f, 10 / 16f, 10 / 16f)), - makeBox(new Vec3d(0 / 16f, 6 / 16f, 6 / 16f), new Vec3d(6 / 16f, 10 / 16f, 10 / 16f))), - (makeBox(new Vec3d(15 / 16f, 5 / 16f, 5 / 16f), new Vec3d(16 / 16f, 11 / 16f, 11 / 16f)), - makeBox(new Vec3d(10 / 16f, 6 / 16f, 6 / 16f), new Vec3d(15 / 16f, 10 / 16f, 10 / 16f)), - makeBox(new Vec3d(10 / 16f, 6 / 16f, 6 / 16f), new Vec3d(16 / 16f, 10 / 16f, 10 / 16f))) + (makeBox(new Vector3d(5 / 16f, 0 / 16f, 5 / 16f), new Vector3d(11 / 16f, 1 / 16f, 11 / 16f)), + makeBox(new Vector3d(6 / 16f, 1 / 16f, 6 / 16f), new Vector3d(10 / 16f, 6 / 16f, 10 / 16f)), + makeBox(new Vector3d(6 / 16f, 0 / 16f, 6 / 16f), new Vector3d(10 / 16f, 6 / 16f, 10 / 16f))), + (makeBox(new Vector3d(5 / 16f, 15 / 16f, 5 / 16f), new Vector3d(11 / 16f, 16 / 16f, 11 / 16f)), + makeBox(new Vector3d(6 / 16f, 10 / 16f, 6 / 16f), new Vector3d(10 / 16f, 15 / 16f, 10 / 16f)), + makeBox(new Vector3d(6 / 16f, 10 / 16f, 6 / 16f), new Vector3d(10 / 16f, 16 / 16f, 10 / 16f))), + (makeBox(new Vector3d(5 / 16f, 5 / 16f, 0 / 16f), new Vector3d(11 / 16f, 11 / 16f, 1 / 16f)), + makeBox(new Vector3d(6 / 16f, 6 / 16f, 1 / 16f), new Vector3d(10 / 16f, 10 / 16f, 6 / 16f)), + makeBox(new Vector3d(6 / 16f, 6 / 16f, 0 / 16f), new Vector3d(10 / 16f, 10 / 16f, 6 / 16f))), + (makeBox(new Vector3d(5 / 16f, 5 / 16f, 15 / 16f), new Vector3d(11 / 16f, 11 / 16f, 16 / 16f)), + makeBox(new Vector3d(6 / 16f, 6 / 16f, 10 / 16f), new Vector3d(10 / 16f, 10 / 16f, 15 / 16f)), + makeBox(new Vector3d(6 / 16f, 6 / 16f, 10 / 16f), new Vector3d(10 / 16f, 10 / 16f, 16 / 16f))), + (makeBox(new Vector3d(0 / 16f, 5 / 16f, 5 / 16f), new Vector3d(1 / 16f, 11 / 16f, 11 / 16f)), + makeBox(new Vector3d(1 / 16f, 6 / 16f, 6 / 16f), new Vector3d(6 / 16f, 10 / 16f, 10 / 16f)), + makeBox(new Vector3d(0 / 16f, 6 / 16f, 6 / 16f), new Vector3d(6 / 16f, 10 / 16f, 10 / 16f))), + (makeBox(new Vector3d(15 / 16f, 5 / 16f, 5 / 16f), new Vector3d(16 / 16f, 11 / 16f, 11 / 16f)), + makeBox(new Vector3d(10 / 16f, 6 / 16f, 6 / 16f), new Vector3d(15 / 16f, 10 / 16f, 10 / 16f)), + makeBox(new Vector3d(10 / 16f, 6 / 16f, 6 / 16f), new Vector3d(16 / 16f, 10 / 16f, 10 / 16f))) ) // Per side, cap only. protected final val Disconnected = Array( - makeBox(new Vec3d(6 / 16f, 5 / 16f, 6 / 16f), new Vec3d(10 / 16f, 6 / 16f, 10 / 16f)), - makeBox(new Vec3d(6 / 16f, 10 / 16f, 6 / 16f), new Vec3d(10 / 16f, 11 / 16f, 10 / 16f)), - makeBox(new Vec3d(6 / 16f, 6 / 16f, 5 / 16f), new Vec3d(10 / 16f, 10 / 16f, 6 / 16f)), - makeBox(new Vec3d(6 / 16f, 6 / 16f, 10 / 16f), new Vec3d(10 / 16f, 10 / 16f, 11 / 16f)), - makeBox(new Vec3d(5 / 16f, 6 / 16f, 6 / 16f), new Vec3d(6 / 16f, 10 / 16f, 10 / 16f)), - makeBox(new Vec3d(10 / 16f, 6 / 16f, 6 / 16f), new Vec3d(11 / 16f, 10 / 16f, 10 / 16f)) + makeBox(new Vector3d(6 / 16f, 5 / 16f, 6 / 16f), new Vector3d(10 / 16f, 6 / 16f, 10 / 16f)), + makeBox(new Vector3d(6 / 16f, 10 / 16f, 6 / 16f), new Vector3d(10 / 16f, 11 / 16f, 10 / 16f)), + makeBox(new Vector3d(6 / 16f, 6 / 16f, 5 / 16f), new Vector3d(10 / 16f, 10 / 16f, 6 / 16f)), + makeBox(new Vector3d(6 / 16f, 6 / 16f, 10 / 16f), new Vector3d(10 / 16f, 10 / 16f, 11 / 16f)), + makeBox(new Vector3d(5 / 16f, 6 / 16f, 6 / 16f), new Vector3d(6 / 16f, 10 / 16f, 10 / 16f)), + makeBox(new Vector3d(10 / 16f, 6 / 16f, 6 / 16f), new Vector3d(11 / 16f, 10 / 16f, 10 / 16f)) ) protected def cableTexture = Array.fill(6)(Textures.getSprite(Textures.Block.Cable)) protected def cableCapTexture = Array.fill(6)(Textures.getSprite(Textures.Block.CableCap)) - object ItemOverride extends ItemOverrideList(Collections.emptyList()) { + object ItemOverride extends ItemOverrideList { class ItemModel(val stack: ItemStack) extends SmartBlockModelBase { - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = { + override def getQuads(state: BlockState, side: Direction, rand: util.Random): util.List[BakedQuad] = { val faces = mutable.ArrayBuffer.empty[BakedQuad] - val color = if (ItemColorizer.hasColor(stack)) ItemColorizer.getColor(stack) else Color.rgbValues(EnumDyeColor.SILVER) + val color = if (ItemColorizer.hasColor(stack)) ItemColorizer.getColor(stack) else Color.rgbValues(DyeColor.LIGHT_GRAY) faces ++= bakeQuads(Middle, cableTexture, Some(color)) faces ++= bakeQuads(Connected(0)._2, cableTexture, Some(color)) @@ -129,7 +119,7 @@ class CableModel extends SmartBlockModelBase { } } - override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = new ItemModel(stack) + override def resolve(originalModel: IBakedModel, stack: ItemStack, world: ClientWorld, entity: LivingEntity): IBakedModel = new ItemModel(stack) } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/DroneModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/DroneModel.scala index 42a7f104ec..5f8c87dce2 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/DroneModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/DroneModel.scala @@ -4,42 +4,42 @@ import java.util import java.util.Collections import li.cil.oc.client.Textures -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.model.BakedQuad -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ItemOverrideList -import net.minecraft.entity.EntityLivingBase +import net.minecraft.block.BlockState +import net.minecraft.client.renderer.model.BakedQuad +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.client.world.ClientWorld +import net.minecraft.entity.LivingEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.Vec3d -import net.minecraft.world.World +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3d -import scala.collection.convert.WrapAsJava.bufferAsJavaList import scala.collection.mutable +import scala.jdk.CollectionConverters._ object DroneModel extends SmartBlockModelBase { override def getOverrides: ItemOverrideList = ItemOverride - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = { + override def getQuads(state: BlockState, side: Direction, rand: util.Random): util.List[BakedQuad] = { val faces = mutable.ArrayBuffer.empty[BakedQuad] - faces ++= Boxes.flatMap(box => bakeQuads(box, Array.fill(6)(droneTexture), None)) + faces ++= Boxes.flatMap(box => bakeQuads(box, Array.fill(6)(droneTexture), None).toSeq) - bufferAsJavaList(faces) + faces.asJava } protected def droneTexture = Textures.getSprite(Textures.Item.DroneItem) protected def Boxes = Array( - makeBox(new Vec3d(1f / 16f, 7f / 16f, 1f / 16f), new Vec3d(7f / 16f, 8f / 16f, 7f / 16f)), - makeBox(new Vec3d(1f / 16f, 7f / 16f, 9f / 16f), new Vec3d(7f / 16f, 8f / 16f, 15f / 16f)), - makeBox(new Vec3d(9f / 16f, 7f / 16f, 1f / 16f), new Vec3d(15f / 16f, 8f / 16f, 7f / 16f)), - makeBox(new Vec3d(9f / 16f, 7f / 16f, 9f / 16f), new Vec3d(15f / 16f, 8f / 16f, 15f / 16f)), - rotateBox(makeBox(new Vec3d(6f / 16f, 6f / 16f, 6f / 16f), new Vec3d(10f / 16f, 9f / 16f, 10f / 16f)), 45) + makeBox(new Vector3d(1f / 16f, 7f / 16f, 1f / 16f), new Vector3d(7f / 16f, 8f / 16f, 7f / 16f)), + makeBox(new Vector3d(1f / 16f, 7f / 16f, 9f / 16f), new Vector3d(7f / 16f, 8f / 16f, 15f / 16f)), + makeBox(new Vector3d(9f / 16f, 7f / 16f, 1f / 16f), new Vector3d(15f / 16f, 8f / 16f, 7f / 16f)), + makeBox(new Vector3d(9f / 16f, 7f / 16f, 9f / 16f), new Vector3d(15f / 16f, 8f / 16f, 15f / 16f)), + rotateBox(makeBox(new Vector3d(6f / 16f, 6f / 16f, 6f / 16f), new Vector3d(10f / 16f, 9f / 16f, 10f / 16f)), 45) ) - object ItemOverride extends ItemOverrideList(Collections.emptyList()) { - override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = DroneModel + object ItemOverride extends ItemOverrideList { + override def resolve(originalModel: IBakedModel, stack: ItemStack, world: ClientWorld, entity: LivingEntity): IBakedModel = DroneModel } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/ModelInitialization.scala b/src/main/scala/li/cil/oc/client/renderer/block/ModelInitialization.scala index bbfd5ddc42..30e80adde1 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/ModelInitialization.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/ModelInitialization.scala @@ -1,81 +1,77 @@ package li.cil.oc.client.renderer.block +import java.util.Random + import li.cil.oc.Constants +import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.common.item.CustomModel -import li.cil.oc.common.item.Delegator -import li.cil.oc.common.item.traits.Delegate -import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.ItemMeshDefinition -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ModelBakery -import net.minecraft.client.renderer.block.model.ModelResourceLocation -import net.minecraft.client.renderer.block.statemap.StateMapperBase +import net.minecraft.client.renderer.BlockModelShapes +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.client.renderer.model.ModelResourceLocation +import net.minecraft.client.world.ClientWorld +import net.minecraft.entity.LivingEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.util.ResourceLocation -import net.minecraft.util.registry.RegistrySimple +import net.minecraft.util.IItemProvider +import net.minecraft.util.Direction import net.minecraftforge.client.event.{ModelBakeEvent, ModelRegistryEvent} -import net.minecraftforge.client.model.{ModelLoader, ModelLoaderRegistry} -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.client.model.data.IDynamicBakedModel +import net.minecraftforge.client.model.data.IModelData +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object ModelInitialization { - final val CableBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "normal") + final val CableBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "") final val CableItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "inventory") - final val NetSplitterBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.NetSplitter, "normal") + final val NetSplitterBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.NetSplitter, "") final val NetSplitterItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.NetSplitter, "inventory") - final val PrintBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Print, "normal") + final val PrintBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Print, "") final val PrintItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Print, "inventory") - final val RobotBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "normal") + final val RobotBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "") final val RobotItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "inventory") - final val RobotAfterimageBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.RobotAfterimage, "normal") - final val RobotAfterimageItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.RobotAfterimage, "inventory") - final val RackBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Rack, "normal") + final val RobotAfterimageBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.RobotAfterimage, "") + final val RackBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Rack, "") private val meshableItems = mutable.ArrayBuffer.empty[Item] - private val itemDelegates = mutable.ArrayBuffer.empty[(String, Delegate)] - private val itemDelegatesCustom = mutable.ArrayBuffer.empty[Delegate with CustomModel] + private val modelRemappings = mutable.Map.empty[ModelResourceLocation, ModelResourceLocation] def preInit(): Unit = { - MinecraftForge.EVENT_BUS.register(this) - registerModel(Constants.BlockName.Cable, CableBlockLocation, CableItemLocation) registerModel(Constants.BlockName.NetSplitter, NetSplitterBlockLocation, NetSplitterItemLocation) registerModel(Constants.BlockName.Print, PrintBlockLocation, PrintItemLocation) registerModel(Constants.BlockName.Robot, RobotBlockLocation, RobotItemLocation) - registerModel(Constants.BlockName.RobotAfterimage, RobotAfterimageBlockLocation, RobotAfterimageItemLocation) + registerModel(Constants.BlockName.RobotAfterimage, RobotAfterimageBlockLocation, null) } @SubscribeEvent def onModelRegistration(event: ModelRegistryEvent): Unit = { - registerItems() - registerSubItems() - registerSubItemsCustom() - } - - // ----------------------------------------------------------------------- // - - def registerModel(instance: Delegate, id: String): Unit = { - instance match { - case customModel: CustomModel => itemDelegatesCustom += customModel - case _ => itemDelegates += id -> instance + val shaper = Minecraft.getInstance.getItemRenderer.getItemModelShaper + for (item <- meshableItems) { + item match { + case custom: CustomModel => custom.registerModelLocations() + case _ => { + Option(api.Items.get(new ItemStack(item))) match { + case Some(descriptor) => + val location = Settings.resourceDomain + ":" + descriptor.name() + shaper.register(item, new ModelResourceLocation(location, "inventory")) + case _ => + } + } + } } } - def registerModel(instance: Item, id: String): Unit = { - meshableItems += instance - } + // ----------------------------------------------------------------------- // - def registerModel(instance: Block, id: String): Unit = { - val item = Item.getItemFromBlock(instance) - registerModel(item, id) + def registerModel(instance: IItemProvider, id: String): Unit = { + meshableItems += instance.asItem } // ----------------------------------------------------------------------- // @@ -85,48 +81,12 @@ object ModelInitialization { val block = descriptor.block() val stack = descriptor.createItemStack(1) - ModelLoader.setCustomModelResourceLocation(stack.getItem, stack.getMetadata, itemLocation) - ModelLoader.setCustomStateMapper(block, new StateMapperBase { - override def getModelResourceLocation(state: IBlockState): ModelResourceLocation = blockLocation - }) - } - - private def registerItems(): Unit = { - val meshDefinition = new ItemMeshDefinition { - override def getModelLocation(stack: ItemStack): ModelResourceLocation = { - Option(api.Items.get(stack)) match { - case Some(descriptor) => - val location = Settings.resourceDomain + ":" + descriptor.name() - new ModelResourceLocation(location, "inventory") - case _ => null - } - } + if (!stack.isEmpty) { + val shaper = Minecraft.getInstance.getItemRenderer.getItemModelShaper + shaper.register(stack.getItem, itemLocation) } - - for (item <- meshableItems) { - ModelLoader.setCustomMeshDefinition(item, meshDefinition) - } - meshableItems.clear() - } - - private def registerSubItems(): Unit = { - for ((id, item) <- itemDelegates) { - val location = Settings.resourceDomain + ":" + id - ModelLoader.setCustomModelResourceLocation(item.parent, item.itemId, new ModelResourceLocation(location, "inventory")) - ModelBakery.registerItemVariants(item.parent, new ResourceLocation(location)) - } - itemDelegates.clear() - } - - private def registerSubItemsCustom(): Unit = { - for (item <- itemDelegatesCustom) { - ModelLoader.setCustomMeshDefinition(item.parent, new ItemMeshDefinition { - override def getModelLocation(stack: ItemStack): ModelResourceLocation = Delegator.subItem(stack) match { - case Some(subItem: CustomModel) => subItem.getModelLocation(stack) - case _ => null - } - }) - item.registerModelLocations() + block.getStateDefinition.getPossibleStates.foreach { + modelRemappings += BlockModelShapes.stateToModelLocation(_) -> blockLocation } } @@ -134,22 +94,56 @@ object ModelInitialization { @SubscribeEvent def onModelBake(e: ModelBakeEvent): Unit = { - val registry = e.getModelRegistry.asInstanceOf[RegistrySimple[ModelResourceLocation, IBakedModel]] - - registry.putObject(CableBlockLocation, CableModel) - registry.putObject(CableItemLocation, CableModel) - registry.putObject(NetSplitterBlockLocation, NetSplitterModel) - registry.putObject(NetSplitterItemLocation, NetSplitterModel) - registry.putObject(PrintBlockLocation, PrintModel) - registry.putObject(PrintItemLocation, PrintModel) - registry.putObject(RobotBlockLocation, RobotModel) - registry.putObject(RobotItemLocation, RobotModel) - registry.putObject(RobotAfterimageBlockLocation, NullModel) - registry.putObject(RobotAfterimageItemLocation, NullModel) - - for (item <- itemDelegatesCustom) { - item.bakeModels(e) + val registry = e.getModelRegistry + + registry.put(CableBlockLocation, CableModel) + registry.put(CableItemLocation, CableModel) + registry.put(NetSplitterBlockLocation, NetSplitterModel) + registry.put(NetSplitterItemLocation, NetSplitterModel) + registry.put(PrintBlockLocation, PrintModel) + registry.put(PrintItemLocation, PrintModel) + registry.put(RobotBlockLocation, RobotModel) + registry.put(RobotItemLocation, RobotModel) + registry.put(RobotAfterimageBlockLocation, NullModel) + + for (item <- meshableItems) item match { + case custom: CustomModel => { + custom.bakeModels(e) + val originalLocation = new ModelResourceLocation(custom.getRegistryName, "inventory") + registry.get(originalLocation) match { + case original: IBakedModel => { + val overrides = new ItemOverrideList { + override def resolve(base: IBakedModel, stack: ItemStack, world: ClientWorld, holder: LivingEntity) = + Option(custom.getModelLocation(stack)).map(registry).getOrElse(original) + } + val fake = new IDynamicBakedModel { + @Deprecated + override def getQuads(state: BlockState, dir: Direction, rand: Random, data: IModelData) = original.getQuads(state, dir, rand, data) + + override def useAmbientOcclusion() = original.useAmbientOcclusion + + override def isGui3d() = original.isGui3d + + override def usesBlockLight() = original.usesBlockLight + + override def isCustomRenderer() = original.isCustomRenderer + + @Deprecated + override def getParticleIcon() = original.getParticleIcon + + @Deprecated + override def getTransforms() = original.getTransforms + + override def getOverrides() = overrides + } + registry.put(originalLocation, fake) + } + case _ => + } + } + case _ => } + meshableItems.clear() val modelOverrides = Map[String, IBakedModel => IBakedModel]( Constants.BlockName.ScreenTier1 -> (_ => ScreenModel), @@ -158,17 +152,19 @@ object ModelInitialization { Constants.BlockName.Rack -> (parent => new ServerRackModel(parent)) ) - registry.getKeys.collect { - case location: ModelResourceLocation => registry.getObject(location) match { - case parent: IBakedModel => - for ((name, model) <- modelOverrides) { - val pattern = s"^${Settings.resourceDomain}:$name#.*" - if (location.toString.matches(pattern)) { - registry.putObject(location, model(parent)) - } + registry.keySet.toArray.foreach { + case location: ModelResourceLocation => { + for ((name, model) <- modelOverrides) { + val pattern = s"^${Settings.resourceDomain}:$name#.*" + if (location.toString.matches(pattern)) { + registry.put(location, model(registry.get(location))) } - case _ => + } } + case _ => + } + for ((real, virtual) <- modelRemappings) { + registry.put(real, registry.get(virtual)) } } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/NetSplitterModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/NetSplitterModel.scala index f446e4895a..6f29ea7cf4 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/NetSplitterModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/NetSplitterModel.scala @@ -3,72 +3,78 @@ package li.cil.oc.client.renderer.block import java.util import java.util.Collections +import li.cil.oc.OpenComputers import li.cil.oc.client.Textures import li.cil.oc.common.block import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.tileentity -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.model.BakedQuad -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ItemOverrideList -import net.minecraft.entity.EntityLivingBase +import net.minecraft.block.BlockState +import net.minecraft.client.world.ClientWorld +import net.minecraft.client.renderer.model.BakedQuad +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.client.renderer.texture.AtlasTexture +import net.minecraft.client.renderer.texture.TextureAtlasSprite +import net.minecraft.entity.LivingEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.Vec3d -import net.minecraft.world.World +import net.minecraft.inventory.container.PlayerContainer +import net.minecraft.util.Direction +import net.minecraft.util.ResourceLocation +import net.minecraft.util.math.vector.Vector3d import net.minecraftforge.client.event.TextureStitchEvent -import net.minecraftforge.common.property.IExtendedBlockState -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.client.model.data.IModelData +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsJava.bufferAsJavaList +import scala.collection.JavaConverters.bufferAsJavaList import scala.collection.mutable object NetSplitterModel extends SmartBlockModelBase { override def getOverrides: ItemOverrideList = ItemOverride - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = - state match { - case extended: IExtendedBlockState => - extended.getValue(block.property.PropertyTile.Tile) match { - case t: tileentity.NetSplitter => - val faces = mutable.ArrayBuffer.empty[BakedQuad] + override def getQuads(state: BlockState, side: Direction, rand: util.Random, data: IModelData): util.List[BakedQuad] = + data match { + case t: tileentity.NetSplitter => + val faces = mutable.ArrayBuffer.empty[BakedQuad] - faces ++= BaseModel - addSideQuads(faces, EnumFacing.values().map(t.isSideOpen)) + faces ++= BaseModel + addSideQuads(faces, Direction.values().map(t.isSideOpen)) - bufferAsJavaList(faces) - case _ => super.getQuads(state, side, rand) - } + bufferAsJavaList(faces) case _ => super.getQuads(state, side, rand) } - protected def splitterTexture = Array( - Textures.getSprite(Textures.Block.NetSplitterTop), - Textures.getSprite(Textures.Block.NetSplitterTop), - Textures.getSprite(Textures.Block.NetSplitterSide), - Textures.getSprite(Textures.Block.NetSplitterSide), - Textures.getSprite(Textures.Block.NetSplitterSide), - Textures.getSprite(Textures.Block.NetSplitterSide) + private def getSprite(location: ResourceLocation, atlas: Option[AtlasTexture]): TextureAtlasSprite = atlas match { + case Some(atls) => atls.getSprite(location) + case None => Textures.getSprite(location) + } + + protected def splitterTexture(atlas: Option[AtlasTexture]) = Array( + getSprite(Textures.Block.NetSplitterTop, atlas), + getSprite(Textures.Block.NetSplitterTop, atlas), + getSprite(Textures.Block.NetSplitterSide, atlas), + getSprite(Textures.Block.NetSplitterSide, atlas), + getSprite(Textures.Block.NetSplitterSide, atlas), + getSprite(Textures.Block.NetSplitterSide, atlas) ) - protected def GenerateBaseModel() = { + protected def GenerateBaseModel(atlas: AtlasTexture) = { val faces = mutable.ArrayBuffer.empty[BakedQuad] // Bottom. - faces ++= bakeQuads(makeBox(new Vec3d(0 / 16f, 0 / 16f, 5 / 16f), new Vec3d(5 / 16f, 5 / 16f, 11 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(11 / 16f, 0 / 16f, 5 / 16f), new Vec3d(16 / 16f, 5 / 16f, 11 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, 0 / 16f, 0 / 16f), new Vec3d(11 / 16f, 5 / 16f, 5 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, 0 / 16f, 11 / 16f), new Vec3d(11 / 16f, 5 / 16f, 16 / 16f)), splitterTexture, None) + faces ++= bakeQuads(makeBox(new Vector3d(0 / 16f, 0 / 16f, 5 / 16f), new Vector3d(5 / 16f, 5 / 16f, 11 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(11 / 16f, 0 / 16f, 5 / 16f), new Vector3d(16 / 16f, 5 / 16f, 11 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, 0 / 16f, 0 / 16f), new Vector3d(11 / 16f, 5 / 16f, 5 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, 0 / 16f, 11 / 16f), new Vector3d(11 / 16f, 5 / 16f, 16 / 16f)), splitterTexture(Some(atlas)), None) // Corners. - faces ++= bakeQuads(makeBox(new Vec3d(0 / 16f, 0 / 16f, 0 / 16f), new Vec3d(5 / 16f, 16 / 16f, 5 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(11 / 16f, 0 / 16f, 0 / 16f), new Vec3d(16 / 16f, 16 / 16f, 5 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(0 / 16f, 0 / 16f, 11 / 16f), new Vec3d(5 / 16f, 16 / 16f, 16 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(11 / 16f, 0 / 16f, 11 / 16f), new Vec3d(16 / 16f, 16 / 16f, 16 / 16f)), splitterTexture, None) + faces ++= bakeQuads(makeBox(new Vector3d(0 / 16f, 0 / 16f, 0 / 16f), new Vector3d(5 / 16f, 16 / 16f, 5 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(11 / 16f, 0 / 16f, 0 / 16f), new Vector3d(16 / 16f, 16 / 16f, 5 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(0 / 16f, 0 / 16f, 11 / 16f), new Vector3d(5 / 16f, 16 / 16f, 16 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(11 / 16f, 0 / 16f, 11 / 16f), new Vector3d(16 / 16f, 16 / 16f, 16 / 16f)), splitterTexture(Some(atlas)), None) // Top. - faces ++= bakeQuads(makeBox(new Vec3d(0 / 16f, 11 / 16f, 5 / 16f), new Vec3d(5 / 16f, 16 / 16f, 11 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(11 / 16f, 11 / 16f, 5 / 16f), new Vec3d(16 / 16f, 16 / 16f, 11 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, 11 / 16f, 0 / 16f), new Vec3d(11 / 16f, 16 / 16f, 5 / 16f)), splitterTexture, None) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, 11 / 16f, 11 / 16f), new Vec3d(11 / 16f, 16 / 16f, 16 / 16f)), splitterTexture, None) + faces ++= bakeQuads(makeBox(new Vector3d(0 / 16f, 11 / 16f, 5 / 16f), new Vector3d(5 / 16f, 16 / 16f, 11 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(11 / 16f, 11 / 16f, 5 / 16f), new Vector3d(16 / 16f, 16 / 16f, 11 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, 11 / 16f, 0 / 16f), new Vector3d(11 / 16f, 16 / 16f, 5 / 16f)), splitterTexture(Some(atlas)), None) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, 11 / 16f, 11 / 16f), new Vector3d(11 / 16f, 16 / 16f, 16 / 16f)), splitterTexture(Some(atlas)), None) faces.toArray } @@ -77,46 +83,42 @@ object NetSplitterModel extends SmartBlockModelBase { @SubscribeEvent def onTextureStitch(e: TextureStitchEvent.Post): Unit = { - BaseModel = GenerateBaseModel() + if (e.getMap.location.equals(PlayerContainer.BLOCK_ATLAS)) BaseModel = GenerateBaseModel(e.getMap) } protected def addSideQuads(faces: mutable.ArrayBuffer[BakedQuad], openSides: Array[Boolean]): Unit = { - val down = openSides(EnumFacing.DOWN.ordinal()) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, if (down) 0 / 16f else 2 / 16f, 5 / 16f), new Vec3d(11 / 16f, 5 / 16f, 11 / 16f)), splitterTexture, None) + val down = openSides(Direction.DOWN.ordinal()) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, if (down) 0 / 16f else 2 / 16f, 5 / 16f), new Vector3d(11 / 16f, 5 / 16f, 11 / 16f)), splitterTexture(None), None) - val up = openSides(EnumFacing.UP.ordinal()) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, 11 / 16f, 5 / 16f), new Vec3d(11 / 16f, if (up) 16 / 16f else 14f / 16f, 11 / 16f)), splitterTexture, None) + val up = openSides(Direction.UP.ordinal()) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, 11 / 16f, 5 / 16f), new Vector3d(11 / 16f, if (up) 16 / 16f else 14f / 16f, 11 / 16f)), splitterTexture(None), None) - val north = openSides(EnumFacing.NORTH.ordinal()) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, 5 / 16f, if (north) 0 / 16f else 2 / 16f), new Vec3d(11 / 16f, 11 / 16f, 5 / 16f)), splitterTexture, None) + val north = openSides(Direction.NORTH.ordinal()) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, 5 / 16f, if (north) 0 / 16f else 2 / 16f), new Vector3d(11 / 16f, 11 / 16f, 5 / 16f)), splitterTexture(None), None) - val south = openSides(EnumFacing.SOUTH.ordinal()) - faces ++= bakeQuads(makeBox(new Vec3d(5 / 16f, 5 / 16f, 11 / 16f), new Vec3d(11 / 16f, 11 / 16f, if (south) 16 / 16f else 14 / 16f)), splitterTexture, None) + val south = openSides(Direction.SOUTH.ordinal()) + faces ++= bakeQuads(makeBox(new Vector3d(5 / 16f, 5 / 16f, 11 / 16f), new Vector3d(11 / 16f, 11 / 16f, if (south) 16 / 16f else 14 / 16f)), splitterTexture(None), None) - val west = openSides(EnumFacing.WEST.ordinal()) - faces ++= bakeQuads(makeBox(new Vec3d(if (west) 0 / 16f else 2 / 16f, 5 / 16f, 5 / 16f), new Vec3d(5 / 16f, 11 / 16f, 11 / 16f)), splitterTexture, None) + val west = openSides(Direction.WEST.ordinal()) + faces ++= bakeQuads(makeBox(new Vector3d(if (west) 0 / 16f else 2 / 16f, 5 / 16f, 5 / 16f), new Vector3d(5 / 16f, 11 / 16f, 11 / 16f)), splitterTexture(None), None) - val east = openSides(EnumFacing.EAST.ordinal()) - faces ++= bakeQuads(makeBox(new Vec3d(11 / 16f, 5 / 16f, 5 / 16f), new Vec3d(if (east) 16 / 16f else 14 / 16f, 11 / 16f, 11 / 16f)), splitterTexture, None) + val east = openSides(Direction.EAST.ordinal()) + faces ++= bakeQuads(makeBox(new Vector3d(11 / 16f, 5 / 16f, 5 / 16f), new Vector3d(if (east) 16 / 16f else 14 / 16f, 11 / 16f, 11 / 16f)), splitterTexture(None), None) } - class ItemModel(val stack: ItemStack) extends SmartBlockModelBase { - val data = new PrintData(stack) - - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = { + object ItemModel extends SmartBlockModelBase { + override def getQuads(state: BlockState, side: Direction, rand: util.Random): util.List[BakedQuad] = { val faces = mutable.ArrayBuffer.empty[BakedQuad] - Textures.Block.bind() - faces ++= BaseModel - addSideQuads(faces, EnumFacing.values().map(_ => false)) + addSideQuads(faces, Direction.values().map(_ => false)) bufferAsJavaList(faces) } } - object ItemOverride extends ItemOverrideList(Collections.emptyList()) { - override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = new ItemModel(stack) + object ItemOverride extends ItemOverrideList { + override def resolve(originalModel: IBakedModel, stack: ItemStack, world: ClientWorld, entity: LivingEntity): IBakedModel = ItemModel } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/PrintModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/PrintModel.scala index 7c8159ad1b..0978978c0e 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/PrintModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/PrintModel.scala @@ -13,52 +13,54 @@ import li.cil.oc.common.tileentity import li.cil.oc.util.Color import li.cil.oc.util.ExtendedAABB import li.cil.oc.util.ExtendedAABB._ -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.model.BakedQuad -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ItemOverrideList -import net.minecraft.entity.EntityLivingBase -import net.minecraft.item.EnumDyeColor +import net.minecraft.block.BlockState +import net.minecraft.client.world.ClientWorld +import net.minecraft.client.renderer.model.BakedQuad +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.client.renderer.texture.MissingTextureSprite +import net.minecraft.client.renderer.texture.TextureAtlasSprite +import net.minecraft.entity.LivingEntity +import net.minecraft.item.DyeColor import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.world.World -import net.minecraftforge.common.property.IExtendedBlockState +import net.minecraft.util.Direction +import net.minecraft.util.ResourceLocation +import net.minecraftforge.client.model.data.IModelData -import scala.collection.convert.WrapAsJava.bufferAsJavaList +import scala.collection.JavaConverters.bufferAsJavaList import scala.collection.mutable object PrintModel extends SmartBlockModelBase { override def getOverrides: ItemOverrideList = ItemOverride - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = - state match { - case extended: IExtendedBlockState => - extended.getValue(block.property.PropertyTile.Tile) match { - case t: tileentity.Print => - val faces = mutable.ArrayBuffer.empty[BakedQuad] + override def getQuads(state: BlockState, side: Direction, rand: util.Random, data: IModelData): util.List[BakedQuad] = + data match { + case t: tileentity.Print => + val faces = mutable.ArrayBuffer.empty[BakedQuad] - for (shape <- t.shapes if !Strings.isNullOrEmpty(shape.texture)) { - val bounds = shape.bounds.rotateTowards(t.facing) - val texture = resolveTexture(shape.texture) - faces ++= bakeQuads(makeBox(bounds.min, bounds.max), Array.fill(6)(texture), shape.tint.getOrElse(White)) - } - - bufferAsJavaList(faces) - case _ => super.getQuads(state, side, rand) + for (shape <- t.shapes if !Strings.isNullOrEmpty(shape.texture)) { + val bounds = shape.bounds.rotateTowards(t.facing) + val texture = resolveTexture(shape.texture) + faces ++= bakeQuads(makeBox(bounds.minVec, bounds.maxVec), Array.fill(6)(texture), shape.tint.getOrElse(White)) } + + bufferAsJavaList(faces) case _ => super.getQuads(state, side, rand) } - private def resolveTexture(name: String) = { - val texture = Textures.getSprite(name) - if (texture.getIconName == "missingno") Textures.getSprite("minecraft:blocks/" + name) + private def resolveTexture(name: String): TextureAtlasSprite = try { + val texture = Textures.getSprite(new ResourceLocation(name)) + if (texture.getName == MissingTextureSprite.getLocation) Textures.getSprite(new ResourceLocation("minecraft:blocks/" + name)) else texture } + catch { + case _: Throwable => Textures.getSprite(MissingTextureSprite.getLocation) + } class ItemModel(val stack: ItemStack) extends SmartBlockModelBase { val data = new PrintData(stack) - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = { + override def getQuads(state: BlockState, side: Direction, rand: util.Random): util.List[BakedQuad] = { val faces = mutable.ArrayBuffer.empty[BakedQuad] val shapes = @@ -69,20 +71,20 @@ object PrintModel extends SmartBlockModelBase { for (shape <- shapes) { val bounds = shape.bounds val texture = resolveTexture(shape.texture) - faces ++= bakeQuads(makeBox(bounds.min, bounds.max), Array.fill(6)(texture), shape.tint.getOrElse(White)) + faces ++= bakeQuads(makeBox(bounds.minVec, bounds.maxVec), Array.fill(6)(texture), shape.tint.getOrElse(White)) } if (shapes.isEmpty) { val bounds = ExtendedAABB.unitBounds val texture = resolveTexture(Settings.resourceDomain + ":blocks/white") - faces ++= bakeQuads(makeBox(bounds.min, bounds.max), Array.fill(6)(texture), Color.rgbValues(EnumDyeColor.LIME)) + faces ++= bakeQuads(makeBox(bounds.minVec, bounds.maxVec), Array.fill(6)(texture), Color.rgbValues(DyeColor.LIME)) } bufferAsJavaList(faces) } } - object ItemOverride extends ItemOverrideList(Collections.emptyList()) { - override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = new ItemModel(stack) + object ItemOverride extends ItemOverrideList { + override def resolve(originalModel: IBakedModel, stack: ItemStack, world: ClientWorld, entity: LivingEntity): IBakedModel = new ItemModel(stack) } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala index 4ec49b7587..cfaa2a82d7 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala @@ -4,17 +4,16 @@ import java.util import java.util.Collections import li.cil.oc.client.Textures -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.model.BakedQuad -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ItemOverrideList -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.entity.EntityLivingBase +import net.minecraft.block.BlockState +import net.minecraft.client.world.ClientWorld +import net.minecraft.client.renderer.model.BakedQuad +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.entity.LivingEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.world.World +import net.minecraft.util.Direction -import scala.collection.convert.WrapAsJava.bufferAsJavaList +import scala.collection.JavaConverters.bufferAsJavaList import scala.collection.mutable object RobotModel extends SmartBlockModelBase { @@ -56,30 +55,30 @@ object RobotModel extends SmartBlockModelBase { (x - 0.5f) * 1.4f + 0.5f, (y - 0.5f) * 1.4f + 0.5f, (z - 0.5f) * 1.4f + 0.5f, - EnumFacing.UP, robotTexture, robotTexture.getInterpolatedU(u * 16), robotTexture.getInterpolatedV(v * 16), + Direction.UP, robotTexture, robotTexture.getU(u * 16), robotTexture.getV(v * 16), White) }.toArray } - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = { + override def getQuads(state: BlockState, side: Direction, rand: util.Random): util.List[BakedQuad] = { val faces = mutable.ArrayBuffer.empty[BakedQuad] - faces += new BakedQuad(quad(top, top1, top2), tint, EnumFacing.NORTH, robotTexture, true, DefaultVertexFormats.ITEM) - faces += new BakedQuad(quad(top, top2, top3), tint, EnumFacing.EAST, robotTexture, true, DefaultVertexFormats.ITEM) - faces += new BakedQuad(quad(top, top3, top4), tint, EnumFacing.SOUTH, robotTexture, true, DefaultVertexFormats.ITEM) - faces += new BakedQuad(quad(top, top4, top1), tint, EnumFacing.WEST, robotTexture, true, DefaultVertexFormats.ITEM) + faces += new BakedQuad(quad(top, top1, top2), tint, Direction.NORTH, robotTexture, true) + faces += new BakedQuad(quad(top, top2, top3), tint, Direction.EAST, robotTexture, true) + faces += new BakedQuad(quad(top, top3, top4), tint, Direction.SOUTH, robotTexture, true) + faces += new BakedQuad(quad(top, top4, top1), tint, Direction.WEST, robotTexture, true) - faces += new BakedQuad(quad(bottom, bottom1, bottom2), tint, EnumFacing.NORTH, robotTexture, true, DefaultVertexFormats.ITEM) - faces += new BakedQuad(quad(bottom, bottom2, bottom3), tint, EnumFacing.EAST, robotTexture, true, DefaultVertexFormats.ITEM) - faces += new BakedQuad(quad(bottom, bottom3, bottom4), tint, EnumFacing.SOUTH, robotTexture, true, DefaultVertexFormats.ITEM) - faces += new BakedQuad(quad(bottom, bottom4, bottom1), tint, EnumFacing.WEST, robotTexture, true, DefaultVertexFormats.ITEM) + faces += new BakedQuad(quad(bottom, bottom1, bottom2), tint, Direction.NORTH, robotTexture, true) + faces += new BakedQuad(quad(bottom, bottom2, bottom3), tint, Direction.EAST, robotTexture, true) + faces += new BakedQuad(quad(bottom, bottom3, bottom4), tint, Direction.SOUTH, robotTexture, true) + faces += new BakedQuad(quad(bottom, bottom4, bottom1), tint, Direction.WEST, robotTexture, true) bufferAsJavaList(faces) } } - object ItemOverride extends ItemOverrideList(Collections.emptyList()) { - override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = ItemModel + object ItemOverride extends ItemOverrideList { + override def resolve(originalModel: IBakedModel, stack: ItemStack, world: ClientWorld, entity: LivingEntity): IBakedModel = ItemModel } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/ScreenModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/ScreenModel.scala index 5069923f19..2526256b4e 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/ScreenModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/ScreenModel.scala @@ -10,71 +10,68 @@ import li.cil.oc.common.Tier import li.cil.oc.common.block import li.cil.oc.common.tileentity import li.cil.oc.util.Color -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.model.BakedQuad -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ItemOverrideList -import net.minecraft.entity.EntityLivingBase +import net.minecraft.block.BlockState +import net.minecraft.client.world.ClientWorld +import net.minecraft.client.renderer.model.BakedQuad +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.entity.LivingEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.world.World -import net.minecraftforge.common.property.IExtendedBlockState +import net.minecraft.util.Direction +import net.minecraftforge.client.model.data.IModelData -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.seqAsJavaList +import scala.collection.convert.ImplicitConversionsToJava._ object ScreenModel extends SmartBlockModelBase { override def getOverrides: ItemOverrideList = ItemOverride - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = { - val safeSide = if (side != null) side else EnumFacing.SOUTH - state match { - case extended: IExtendedBlockState => - extended.getValue(block.property.PropertyTile.Tile) match { - case screen: tileentity.Screen => - val facing = screen.toLocal(safeSide) + override def getQuads(state: BlockState, side: Direction, rand: util.Random, data: IModelData): util.List[BakedQuad] = { + val safeSide = if (side != null) side else Direction.SOUTH + data match { + case screen: tileentity.Screen => + val facing = screen.toLocal(safeSide) - val (x, y) = screen.localPosition - var px = xy2part(x, screen.width - 1) - var py = xy2part(y, screen.height - 1) - if ((safeSide == EnumFacing.DOWN || screen.facing == EnumFacing.DOWN) && safeSide != screen.facing) { - px = 2 - px - py = 2 - py - } - val rotation = - if (safeSide == EnumFacing.UP) screen.yaw.getHorizontalIndex - else if (safeSide == EnumFacing.DOWN) -screen.yaw.getHorizontalIndex - else 0 + val (x, y) = screen.localPosition + var px = xy2part(x, screen.width - 1) + var py = xy2part(y, screen.height - 1) + if ((safeSide == Direction.DOWN || screen.facing == Direction.DOWN) && safeSide != screen.facing) { + px = 2 - px + py = 2 - py + } + val rotation = + if (safeSide == Direction.UP) screen.yaw.get2DDataValue + else if (safeSide == Direction.DOWN) -screen.yaw.get2DDataValue + else 0 - def pitch = if (screen.pitch == EnumFacing.NORTH) 0 else 1 - val texture = - if (screen.width == 1 && screen.height == 1) { - if (facing == EnumFacing.SOUTH) - Textures.Block.Screen.SingleFront(pitch) - else - Textures.Block.Screen.Single(safeSide.getIndex) - } - else if (screen.width == 1) { - if (facing == EnumFacing.SOUTH) - Textures.Block.Screen.VerticalFront(pitch)(py) - else - Textures.Block.Screen.Vertical(pitch)(py)(facing.getIndex) - } - else if (screen.height == 1) { - if (facing == EnumFacing.SOUTH) - Textures.Block.Screen.HorizontalFront(pitch)(px) - else - Textures.Block.Screen.Horizontal(pitch)(px)(facing.getIndex) - } - else { - if (facing == EnumFacing.SOUTH) - Textures.Block.Screen.MultiFront(pitch)(py)(px) - else - Textures.Block.Screen.Multi(pitch)(py)(px)(facing.getIndex) - } + def pitch = if (screen.pitch == Direction.NORTH) 0 else 1 + val texture = + if (screen.width == 1 && screen.height == 1) { + if (facing == Direction.SOUTH) + Textures.Block.Screen.SingleFront(pitch) + else + Textures.Block.Screen.Single(safeSide.get3DDataValue) + } + else if (screen.width == 1) { + if (facing == Direction.SOUTH) + Textures.Block.Screen.VerticalFront(pitch)(py) + else + Textures.Block.Screen.Vertical(pitch)(py)(facing.get3DDataValue) + } + else if (screen.height == 1) { + if (facing == Direction.SOUTH) + Textures.Block.Screen.HorizontalFront(pitch)(px) + else + Textures.Block.Screen.Horizontal(pitch)(px)(facing.get3DDataValue) + } + else { + if (facing == Direction.SOUTH) + Textures.Block.Screen.MultiFront(pitch)(py)(px) + else + Textures.Block.Screen.Multi(pitch)(py)(px)(facing.get3DDataValue) + } - seqAsJavaList(Seq(bakeQuad(safeSide, Textures.getSprite(texture), Some(screen.getColor), rotation))) - case _ => super.getQuads(state, safeSide, rand) - } + seqAsJavaList(Seq(bakeQuad(safeSide, Textures.getSprite(texture), Some(screen.getColor), rotation))) case _ => super.getQuads(state, safeSide, rand) } } @@ -88,18 +85,18 @@ object ScreenModel extends SmartBlockModelBase { case _ => Color.byTier(Tier.One) } - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = { + override def getQuads(state: BlockState, side: Direction, rand: util.Random): util.List[BakedQuad] = { val result = - if (side == EnumFacing.NORTH || side == null) + if (side == Direction.NORTH || side == null) Textures.Block.Screen.SingleFront(0) else Textures.Block.Screen.Single(side.ordinal()) - seqAsJavaList(Seq(bakeQuad(if (side != null) side else EnumFacing.SOUTH, Textures.getSprite(result), Some(Color.rgbValues(color)), 0))) + seqAsJavaList(Seq(bakeQuad(if (side != null) side else Direction.SOUTH, Textures.getSprite(result), Some(Color.rgbValues(color)), 0))) } } - object ItemOverride extends ItemOverrideList(Collections.emptyList()) { - override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = new ItemModel(stack) + object ItemOverride extends ItemOverrideList { + override def resolve(originalModel: IBakedModel, stack: ItemStack, world: ClientWorld, entity: LivingEntity): IBakedModel = new ItemModel(stack) } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/ServerRackModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/ServerRackModel.scala index 9b9e12740b..0632457781 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/ServerRackModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/ServerRackModel.scala @@ -8,56 +8,52 @@ import li.cil.oc.api.event.RackMountableRenderEvent import li.cil.oc.client.Textures import li.cil.oc.common.block import li.cil.oc.common.tileentity -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.model.BakedQuad -import net.minecraft.client.renderer.block.model.IBakedModel -import net.minecraft.client.renderer.block.model.ItemOverrideList -import net.minecraft.entity.EntityLivingBase +import net.minecraft.block.BlockState +import net.minecraft.client.world.ClientWorld +import net.minecraft.client.renderer.model.BakedQuad +import net.minecraft.client.renderer.model.IBakedModel +import net.minecraft.client.renderer.model.ItemOverrideList +import net.minecraft.entity.LivingEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.Vec3d -import net.minecraft.world.World +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3d import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.common.property.IExtendedBlockState +import net.minecraftforge.client.model.data.IModelData -import scala.collection.convert.WrapAsJava.bufferAsJavaList +import scala.collection.JavaConverters.bufferAsJavaList import scala.collection.mutable class ServerRackModel(val parent: IBakedModel) extends SmartBlockModelBase { override def getOverrides: ItemOverrideList = ItemOverride - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = - state match { - case extended: IExtendedBlockState => - extended.getValue(block.property.PropertyTile.Tile) match { - case rack: tileentity.Rack => - val facing = rack.facing - val faces = mutable.ArrayBuffer.empty[BakedQuad] + override def getQuads(state: BlockState, side: Direction, rand: util.Random, data: IModelData): util.List[BakedQuad] = + data match { + case rack: tileentity.Rack => + val facing = rack.facing + val faces = mutable.ArrayBuffer.empty[BakedQuad] - for (side <- EnumFacing.values if side != facing) { - faces ++= bakeQuads(Case(side.getIndex), serverRackTexture, None) - } + for (side <- Direction.values if side != facing) { + faces ++= bakeQuads(Case(side.get3DDataValue), serverRackTexture, None) + } - val textures = serverTexture - val defaultFront = Textures.getSprite(Textures.Block.RackFront) - for (slot <- 0 until 4) rack.getMountable(slot) match { - case mountable: RackMountable => - val event = new RackMountableRenderEvent.Block(rack, slot, rack.lastData(slot), side) - MinecraftForge.EVENT_BUS.post(event) - if (!event.isCanceled) { - if (event.getFrontTextureOverride != null) { - (2 until 6).foreach(textures(_) = event.getFrontTextureOverride) - } else { - (2 until 6).foreach(textures(_) = defaultFront) - } - faces ++= bakeQuads(Servers(slot), textures, None) - } - case _ => + val textures = serverTexture + val defaultFront = Textures.getSprite(Textures.Block.RackFront) + for (slot <- 0 until 4) rack.getMountable(slot) match { + case mountable: RackMountable => + val event = new RackMountableRenderEvent.Block(rack, slot, rack.lastData(slot), side) + MinecraftForge.EVENT_BUS.post(event) + if (!event.isCanceled) { + if (event.getFrontTextureOverride != null) { + (2 until 6).foreach(textures(_) = event.getFrontTextureOverride) + } else { + (2 until 6).foreach(textures(_) = defaultFront) + } + faces ++= bakeQuads(Servers(slot), textures, None) } - - bufferAsJavaList(faces) - case _ => super.getQuads(state, side, rand) + case _ => } + + bufferAsJavaList(faces) case _ => super.getQuads(state, side, rand) } @@ -80,23 +76,23 @@ class ServerRackModel(val parent: IBakedModel) extends SmartBlockModelBase { ) protected final val Case = Array( - makeBox(new Vec3d(0 / 16f, 0 / 16f, 0 / 16f), new Vec3d(16 / 16f, 2 / 16f, 16 / 16f)), - makeBox(new Vec3d(0 / 16f, 14 / 16f, 0 / 16f), new Vec3d(16 / 16f, 16 / 16f, 16 / 16f)), - makeBox(new Vec3d(0 / 16f, 2 / 16f, 0 / 16f), new Vec3d(16 / 16f, 14 / 16f, 0.99f / 16f)), - makeBox(new Vec3d(0 / 16f, 2 / 16f, 15.01f / 16f), new Vec3d(16 / 16f, 14 / 16f, 16 / 16f)), - makeBox(new Vec3d(0 / 16f, 2 / 16f, 0 / 16f), new Vec3d(0.99f / 16f, 14 / 16f, 16 / 16f)), - makeBox(new Vec3d(15.01f / 16f, 2 / 16f, 0 / 16f), new Vec3d(16 / 16f, 14f / 16f, 16 / 16f)) + makeBox(new Vector3d(0 / 16f, 0 / 16f, 0 / 16f), new Vector3d(16 / 16f, 2 / 16f, 16 / 16f)), + makeBox(new Vector3d(0 / 16f, 14 / 16f, 0 / 16f), new Vector3d(16 / 16f, 16 / 16f, 16 / 16f)), + makeBox(new Vector3d(0 / 16f, 2 / 16f, 0 / 16f), new Vector3d(16 / 16f, 14 / 16f, 0.99f / 16f)), + makeBox(new Vector3d(0 / 16f, 2 / 16f, 15.01f / 16f), new Vector3d(16 / 16f, 14 / 16f, 16 / 16f)), + makeBox(new Vector3d(0 / 16f, 2 / 16f, 0 / 16f), new Vector3d(0.99f / 16f, 14 / 16f, 16 / 16f)), + makeBox(new Vector3d(15.01f / 16f, 2 / 16f, 0 / 16f), new Vector3d(16 / 16f, 14f / 16f, 16 / 16f)) ) protected final val Servers = Array( - makeBox(new Vec3d(0.5f / 16f, 11 / 16f, 0.5f / 16f), new Vec3d(15.5f / 16f, 14 / 16f, 15.5f / 16f)), - makeBox(new Vec3d(0.5f / 16f, 8 / 16f, 0.5f / 16f), new Vec3d(15.5f / 16f, 11 / 16f, 15.5f / 16f)), - makeBox(new Vec3d(0.5f / 16f, 5 / 16f, 0.5f / 16f), new Vec3d(15.5f / 16f, 8 / 16f, 15.5f / 16f)), - makeBox(new Vec3d(0.5f / 16f, 2 / 16f, 0.5f / 16f), new Vec3d(15.5f / 16f, 5 / 16f, 15.5f / 16f)) + makeBox(new Vector3d(0.5f / 16f, 11 / 16f, 0.5f / 16f), new Vector3d(15.5f / 16f, 14 / 16f, 15.5f / 16f)), + makeBox(new Vector3d(0.5f / 16f, 8 / 16f, 0.5f / 16f), new Vector3d(15.5f / 16f, 11 / 16f, 15.5f / 16f)), + makeBox(new Vector3d(0.5f / 16f, 5 / 16f, 0.5f / 16f), new Vector3d(15.5f / 16f, 8 / 16f, 15.5f / 16f)), + makeBox(new Vector3d(0.5f / 16f, 2 / 16f, 0.5f / 16f), new Vector3d(15.5f / 16f, 5 / 16f, 15.5f / 16f)) ) - object ItemOverride extends ItemOverrideList(Collections.emptyList()) { - override def handleItemState(originalModel: IBakedModel, stack: ItemStack, world: World, entity: EntityLivingBase): IBakedModel = parent + object ItemOverride extends ItemOverrideList { + override def resolve(originalModel: IBakedModel, stack: ItemStack, world: ClientWorld, entity: LivingEntity): IBakedModel = parent } } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala b/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala index 88479d1899..6d65bfdd55 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala @@ -4,32 +4,37 @@ import java.util import java.util.Collections import li.cil.oc.client.Textures -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.block.model._ +import net.minecraft.client.renderer.model._ import net.minecraft.client.renderer.texture.TextureAtlasSprite -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.Vec3d -import org.lwjgl.util.vector.Vector3f +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.util.math.vector.Vector3f trait SmartBlockModelBase extends IBakedModel { - override def getOverrides: ItemOverrideList = ItemOverrideList.NONE + override def getOverrides: ItemOverrideList = ItemOverrideList.EMPTY - override def getQuads(state: IBlockState, side: EnumFacing, rand: Long): util.List[BakedQuad] = Collections.emptyList() + @Deprecated + override def getQuads(state: BlockState, side: Direction, rand: util.Random): util.List[BakedQuad] = Collections.emptyList() - override def isAmbientOcclusion = true + override def useAmbientOcclusion = true override def isGui3d = true - override def isBuiltInRenderer = false + override def usesBlockLight = true + + override def isCustomRenderer = false // Note: we don't care about the actual texture here, we just need the block // texture atlas. So any of our textures we know is loaded into it will do. - override def getParticleTexture = Textures.getSprite(Textures.Block.GenericTop) + @Deprecated + override def getParticleIcon = Textures.getSprite(Textures.Block.GenericTop) - override def getItemCameraTransforms = DefaultBlockCameraTransforms + @Deprecated + override def getTransforms = DefaultBlockCameraTransforms + @Deprecated protected final val DefaultBlockCameraTransforms = { val gui = new ItemTransformVec3f(new Vector3f(30, 225, 0), new Vector3f(0, 0, 0), new Vector3f(0.625f, 0.625f, 0.625f)) val ground = new ItemTransformVec3f(new Vector3f(0, 0, 0), new Vector3f(0, 3, 0), new Vector3f(0.25f, 0.25f, 0.25f)) @@ -39,46 +44,46 @@ trait SmartBlockModelBase extends IBakedModel { val firstperson_lefthand = new ItemTransformVec3f(new Vector3f(0, 225, 0), new Vector3f(0, 0, 0), new Vector3f(0.40f, 0.40f, 0.40f)) // scale(0.0625f): see ItemTransformVec3f.Deserializer.deserialize. - gui.translation.scale(0.0625f) - ground.translation.scale(0.0625f) - fixed.translation.scale(0.0625f) - thirdperson_righthand.translation.scale(0.0625f) - firstperson_righthand.translation.scale(0.0625f) - firstperson_lefthand.translation.scale(0.0625f) + gui.translation.mul(0.0625f) + ground.translation.mul(0.0625f) + fixed.translation.mul(0.0625f) + thirdperson_righthand.translation.mul(0.0625f) + firstperson_righthand.translation.mul(0.0625f) + firstperson_lefthand.translation.mul(0.0625f) new ItemCameraTransforms( - ItemTransformVec3f.DEFAULT, + ItemTransformVec3f.NO_TRANSFORM, thirdperson_righthand, firstperson_lefthand, firstperson_righthand, - ItemTransformVec3f.DEFAULT, + ItemTransformVec3f.NO_TRANSFORM, gui, ground, fixed) } - protected def missingModel = Minecraft.getMinecraft.getRenderItem.getItemModelMesher.getModelManager.getMissingModel + protected def missingModel = Minecraft.getInstance.getModelManager.getMissingModel // Standard faces for a unit cube. protected final val UnitCube = Array( - Array(new Vec3d(0, 0, 1), new Vec3d(0, 0, 0), new Vec3d(1, 0, 0), new Vec3d(1, 0, 1)), - Array(new Vec3d(0, 1, 0), new Vec3d(0, 1, 1), new Vec3d(1, 1, 1), new Vec3d(1, 1, 0)), - Array(new Vec3d(1, 1, 0), new Vec3d(1, 0, 0), new Vec3d(0, 0, 0), new Vec3d(0, 1, 0)), - Array(new Vec3d(0, 1, 1), new Vec3d(0, 0, 1), new Vec3d(1, 0, 1), new Vec3d(1, 1, 1)), - Array(new Vec3d(0, 1, 0), new Vec3d(0, 0, 0), new Vec3d(0, 0, 1), new Vec3d(0, 1, 1)), - Array(new Vec3d(1, 1, 1), new Vec3d(1, 0, 1), new Vec3d(1, 0, 0), new Vec3d(1, 1, 0)) + Array(new Vector3d(0, 0, 1), new Vector3d(0, 0, 0), new Vector3d(1, 0, 0), new Vector3d(1, 0, 1)), + Array(new Vector3d(0, 1, 0), new Vector3d(0, 1, 1), new Vector3d(1, 1, 1), new Vector3d(1, 1, 0)), + Array(new Vector3d(1, 1, 0), new Vector3d(1, 0, 0), new Vector3d(0, 0, 0), new Vector3d(0, 1, 0)), + Array(new Vector3d(0, 1, 1), new Vector3d(0, 0, 1), new Vector3d(1, 0, 1), new Vector3d(1, 1, 1)), + Array(new Vector3d(0, 1, 0), new Vector3d(0, 0, 0), new Vector3d(0, 0, 1), new Vector3d(0, 1, 1)), + Array(new Vector3d(1, 1, 1), new Vector3d(1, 0, 1), new Vector3d(1, 0, 0), new Vector3d(1, 1, 0)) ) // Planes perpendicular to facings. Negative values mean we mirror along that, // axis which is done to mirror back faces and the y axis (because up is // positive but for our texture coordinates down is positive). protected final val Planes = Array( - (new Vec3d(1, 0, 0), new Vec3d(0, 0, -1)), - (new Vec3d(1, 0, 0), new Vec3d(0, 0, 1)), - (new Vec3d(-1, 0, 0), new Vec3d(0, -1, 0)), - (new Vec3d(1, 0, 0), new Vec3d(0, -1, 0)), - (new Vec3d(0, 0, 1), new Vec3d(0, -1, 0)), - (new Vec3d(0, 0, -1), new Vec3d(0, -1, 0)) + (new Vector3d(1, 0, 0), new Vector3d(0, 0, -1)), + (new Vector3d(1, 0, 0), new Vector3d(0, 0, 1)), + (new Vector3d(-1, 0, 0), new Vector3d(0, -1, 0)), + (new Vector3d(1, 0, 0), new Vector3d(0, -1, 0)), + (new Vector3d(0, 0, 1), new Vector3d(0, -1, 0)), + (new Vector3d(0, 0, -1), new Vector3d(0, -1, 0)) ) protected final val White = 0xFFFFFF @@ -87,34 +92,34 @@ trait SmartBlockModelBase extends IBakedModel { * Generates a list of arrays, each containing the four vertices making up a * face of the box with the specified size. */ - protected def makeBox(from: Vec3d, to: Vec3d) = { + protected def makeBox(from: Vector3d, to: Vector3d) = { val minX = math.min(from.x, to.x) val minY = math.min(from.y, to.y) val minZ = math.min(from.z, to.z) val maxX = math.max(from.x, to.x) val maxY = math.max(from.y, to.y) val maxZ = math.max(from.z, to.z) - UnitCube.map(face => face.map(vertex => new Vec3d( + UnitCube.map(face => face.map(vertex => new Vector3d( math.max(minX, math.min(maxX, vertex.x)), math.max(minY, math.min(maxY, vertex.y)), math.max(minZ, math.min(maxZ, vertex.z))))) } - protected def rotateVector(v: Vec3d, angle: Double, axis: Vec3d) = { + protected def rotateVector(v: Vector3d, angle: Double, axis: Vector3d) = { // vrot = v * cos(angle) + (axis x v) * sin(angle) + axis * (axis dot v)(1 - cos(angle)) - def scale(v: Vec3d, s: Double) = new Vec3d(v.x * s, v.y * s, v.z * s) + def scale(v: Vector3d, s: Double) = v.scale(s) val cosAngle = math.cos(angle) val sinAngle = math.sin(angle) scale(v, cosAngle). - add(scale(axis.crossProduct(v), sinAngle)). - add(scale(axis, axis.dotProduct(v) * (1 - cosAngle))) + add(scale(axis.cross(v), sinAngle)). + add(scale(axis, axis.dot(v) * (1 - cosAngle))) } - protected def rotateFace(face: Array[Vec3d], angle: Double, axis: Vec3d, around: Vec3d = new Vec3d(0.5, 0.5, 0.5)) = { + protected def rotateFace(face: Array[Vector3d], angle: Double, axis: Vector3d, around: Vector3d = new Vector3d(0.5, 0.5, 0.5)) = { face.map(v => rotateVector(v.subtract(around), angle, axis).add(around)) } - protected def rotateBox(box: Array[Array[Vec3d]], angle: Double, axis: Vec3d = new Vec3d(0, 1, 0), around: Vec3d = new Vec3d(0.5, 0.5, 0.5)) = { + protected def rotateBox(box: Array[Array[Vector3d]], angle: Double, axis: Vector3d = new Vector3d(0, 1, 0), around: Vector3d = new Vector3d(0.5, 0.5, 0.5)) = { box.map(face => rotateFace(face, angle, axis, around)) } @@ -123,7 +128,7 @@ trait SmartBlockModelBase extends IBakedModel { *

    * Usually used to generate the quads for a cube previously generated using makeBox(). */ - protected def bakeQuads(box: Array[Array[Vec3d]], texture: Array[TextureAtlasSprite], color: Option[Int]): Array[BakedQuad] = { + protected def bakeQuads(box: Array[Array[Vector3d]], texture: Array[TextureAtlasSprite], color: Option[Int]): Array[BakedQuad] = { val colorRGB = color.getOrElse(White) bakeQuads(box, texture, colorRGB) } @@ -133,33 +138,33 @@ trait SmartBlockModelBase extends IBakedModel { *

    * Usually used to generate the quads for a cube previously generated using makeBox(). */ - protected def bakeQuads(box: Array[Array[Vec3d]], texture: Array[TextureAtlasSprite], colorRGB: Int): Array[BakedQuad] = { - EnumFacing.values.map(side => { - val vertices = box(side.getIndex) - val data = quadData(vertices, side, texture(side.getIndex), colorRGB, 0) - new BakedQuad(data, -1, side, texture(side.getIndex), true, DefaultVertexFormats.ITEM) + protected def bakeQuads(box: Array[Array[Vector3d]], texture: Array[TextureAtlasSprite], colorRGB: Int): Array[BakedQuad] = { + Direction.values.map(side => { + val vertices = box(side.get3DDataValue) + val data = quadData(vertices, side, texture(side.get3DDataValue), colorRGB, 0) + new BakedQuad(data, -1, side, texture(side.get3DDataValue), true) }) } /** * Create a single BakedQuad of a unit cube's specified side. */ - protected def bakeQuad(side: EnumFacing, texture: TextureAtlasSprite, color: Option[Int], rotation: Int) = { + protected def bakeQuad(side: Direction, texture: TextureAtlasSprite, color: Option[Int], rotation: Int) = { val colorRGB = color.getOrElse(White) - val vertices = UnitCube(side.getIndex) + val vertices = UnitCube(side.get3DDataValue) val data = quadData(vertices, side, texture, colorRGB, rotation) - new BakedQuad(data, -1, side, texture, true, DefaultVertexFormats.ITEM) + new BakedQuad(data, -1, side, texture, true) } // Generate raw data used for a BakedQuad based on the specified facing, vertices, texture and rotation. // The UV coordinates are generated from the positions of the vertices, i.e. they are simply cube- // mapped. This is good enough for us. - protected def quadData(vertices: Array[Vec3d], facing: EnumFacing, texture: TextureAtlasSprite, colorRGB: Int, rotation: Int): Array[Int] = { - val (uAxis, vAxis) = Planes(facing.getIndex) + protected def quadData(vertices: Array[Vector3d], facing: Direction, texture: TextureAtlasSprite, colorRGB: Int, rotation: Int): Array[Int] = { + val (uAxis, vAxis) = Planes(facing.get3DDataValue) val rot = (rotation + 4) % 4 vertices.flatMap(vertex => { - var u = vertex.dotProduct(uAxis) - var v = vertex.dotProduct(vAxis) + var u = vertex.dot(uAxis) + var v = vertex.dot(vAxis) if (uAxis.x + uAxis.y + uAxis.z < 0) u = 1 + u if (vAxis.x + vAxis.y + vAxis.z < 0) v = 1 + v for (i <- 0 until rot) { @@ -168,15 +173,15 @@ trait SmartBlockModelBase extends IBakedModel { u = v v = (-(tmp - 0.5)) + 0.5 } - rawData(vertex.x, vertex.y, vertex.z, facing, texture, texture.getInterpolatedU(u * 16), texture.getInterpolatedV(v * 16), colorRGB) + rawData(vertex.x, vertex.y, vertex.z, facing, texture, texture.getU(u * 16), texture.getV(v * 16), colorRGB) }) } // See FaceBakery#storeVertexData. - protected def rawData(x: Double, y: Double, z: Double, face: EnumFacing, texture: TextureAtlasSprite, u: Float, v: Float, colorRGB: Int) = { - val vx = (face.getFrontOffsetX * 127) & 0xFF - val vy = (face.getFrontOffsetY * 127) & 0xFF - val vz = (face.getFrontOffsetZ * 127) & 0xFF + protected def rawData(x: Double, y: Double, z: Double, face: Direction, texture: TextureAtlasSprite, u: Float, v: Float, colorRGB: Int) = { + val vx = (face.getStepX * 127) & 0xFF + val vy = (face.getStepY * 127) & 0xFF + val vz = (face.getStepZ * 127) & 0xFF Array( java.lang.Float.floatToRawIntBits(x.toFloat), @@ -185,12 +190,12 @@ trait SmartBlockModelBase extends IBakedModel { getFaceShadeColor(face, colorRGB), java.lang.Float.floatToRawIntBits(u), java.lang.Float.floatToRawIntBits(v), - vx | (vy << 0x08) | (vz << 0x10) + 0, vx | (vy << 0x08) | (vz << 0x10) ) } // See FaceBakery. - protected def getFaceShadeColor(face: EnumFacing, colorRGB: Int): Int = { + protected def getFaceShadeColor(face: Direction, colorRGB: Int): Int = { val brightness = getFaceBrightness(face) val b = (colorRGB >> 16) & 0xFF val g = (colorRGB >> 8) & 0xFF @@ -200,12 +205,12 @@ trait SmartBlockModelBase extends IBakedModel { private def shade(value: Int, brightness: Float) = (brightness * value).toInt max 0 min 255 - protected def getFaceBrightness(face: EnumFacing): Float = { + protected def getFaceBrightness(face: Direction): Float = { face match { - case EnumFacing.DOWN => 0.5f - case EnumFacing.UP => 1.0f - case EnumFacing.NORTH | EnumFacing.SOUTH => 0.8f - case EnumFacing.WEST | EnumFacing.EAST => 0.6f + case Direction.DOWN => 0.5f + case Direction.UP => 1.0f + case Direction.NORTH | Direction.SOUTH => 0.8f + case Direction.WEST | Direction.EAST => 0.6f } } } diff --git a/src/main/scala/li/cil/oc/client/renderer/entity/DroneRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/entity/DroneRenderer.scala index 3f4d1ab441..a6a7132373 100644 --- a/src/main/scala/li/cil/oc/client/renderer/entity/DroneRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/entity/DroneRenderer.scala @@ -1,27 +1,50 @@ package li.cil.oc.client.renderer.entity +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures import li.cil.oc.common.entity.Drone import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.entity.Render +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.RenderType +import net.minecraft.client.renderer.entity.EntityRenderer +import net.minecraft.client.renderer.entity.EntityRendererManager +import net.minecraft.client.renderer.texture.OverlayTexture +import net.minecraft.util.math.MathHelper +import net.minecraftforge.fml.client.registry.IRenderFactory -object DroneRenderer extends Render[Drone](Minecraft.getMinecraft.getRenderManager) { +object DroneRenderer extends IRenderFactory[Drone] { val model = new ModelQuadcopter() - override def doRender(entity: Drone, x: Double, y: Double, z: Double, yaw: Float, dt: Float) { - bindEntityTexture(entity) - GlStateManager.pushMatrix() - RenderState.pushAttrib() + override def createRenderFor(manager: EntityRendererManager) = new DroneRenderer(manager) +} - GlStateManager.translate(x, y + 2 / 16f, z) +class DroneRenderer(manager: EntityRendererManager) extends EntityRenderer[Drone](manager) { + override def render(entity: Drone, yaw: Float, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int): Unit = { + val renderType = getRenderType(entity) + if (renderType != null) { + stack.pushPose() + stack.translate(0, 2f / 16f, 0) + val builder = buffer.getBuffer(renderType) + DroneRenderer.model.prepareMobModel(entity, 0, 0, dt) + val xRot = MathHelper.rotLerp(dt, entity.xRotO, entity.xRot) + val yRot = MathHelper.rotLerp(dt, entity.yRotO, entity.yRot) + DroneRenderer.model.setupAnim(entity, 0, 0, entity.tickCount, yRot, xRot) + DroneRenderer.model.renderToBuffer(stack, builder, light, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1) + stack.popPose() + } + super.render(entity, yaw, dt, stack, buffer, light) + } - model.render(entity, 0, 0, 0, 0, 0, dt) + override def getTextureLocation(entity: Drone) = Textures.Model.Drone - RenderState.popAttrib() - GlStateManager.popMatrix() + def getRenderType(entity: Drone): RenderType = { + val mc = Minecraft.getInstance + val texture = getTextureLocation(entity) + if (!entity.isInvisible) DroneRenderer.model.renderType(texture) + else if (!entity.isInvisibleTo(mc.player)) RenderType.itemEntityTranslucentCull(texture) + else if (mc.shouldEntityAppearGlowing(entity)) RenderType.outline(texture) + else null } - - override def getEntityTexture(entity: Drone) = Textures.Model.Drone } diff --git a/src/main/scala/li/cil/oc/client/renderer/entity/ModelQuadcopter.scala b/src/main/scala/li/cil/oc/client/renderer/entity/ModelQuadcopter.scala index 6b8e51d110..434d645e32 100644 --- a/src/main/scala/li/cil/oc/client/renderer/entity/ModelQuadcopter.scala +++ b/src/main/scala/li/cil/oc/client/renderer/entity/ModelQuadcopter.scala @@ -1,179 +1,115 @@ package li.cil.oc.client.renderer.entity +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.common.entity.Drone -import li.cil.oc.util.RenderState -import net.minecraft.client.model.ModelBase -import net.minecraft.client.model.ModelRenderer -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.Entity -import net.minecraft.util.math.Vec3d -import org.lwjgl.opengl.GL11 - -final class ModelQuadcopter extends ModelBase { - val body = new ModelRenderer(this, "body") - val wing0 = new ModelRenderer(this, "wing0") - val wing1 = new ModelRenderer(this, "wing1") - val wing2 = new ModelRenderer(this, "wing2") - val wing3 = new ModelRenderer(this, "wing3") - val light0 = new ModelRenderer(this, "light0") - val light1 = new ModelRenderer(this, "light1") - val light2 = new ModelRenderer(this, "light2") - val light3 = new ModelRenderer(this, "light3") - - textureWidth = 64 - textureHeight = 32 - - setTextureOffset("body.middle", 0, 23) - setTextureOffset("body.top", 0, 1) - setTextureOffset("body.bottom", 0, 17) - setTextureOffset("wing0.flap0", 0, 9) - setTextureOffset("wing0.pin0", 0, 27) - setTextureOffset("wing1.flap1", 0, 9) - setTextureOffset("wing1.pin1", 0, 27) - setTextureOffset("wing2.flap2", 0, 9) - setTextureOffset("wing2.pin2", 0, 27) - setTextureOffset("wing3.flap3", 0, 9) - setTextureOffset("wing3.pin3", 0, 27) - - setTextureOffset("light0.flap0", 24, 0) - setTextureOffset("light1.flap1", 24, 0) - setTextureOffset("light2.flap2", 24, 0) - setTextureOffset("light3.flap3", 24, 0) - - body.addBox("top", -3, 1, -3, 6, 1, 6).rotateAngleY = math.toRadians(45).toFloat - body.addBox("middle", -1, 0, -1, 2, 1, 2).rotateAngleY = math.toRadians(45).toFloat - body.addBox("bottom", -2, -1, -2, 4, 1, 4).rotateAngleY = math.toRadians(45).toFloat - wing0.addBox("flap0", 1, 0, -7, 6, 1, 6) - wing0.addBox("pin0", 2, -1, -3, 1, 3, 1) - wing1.addBox("flap1", 1, 0, 1, 6, 1, 6) - wing1.addBox("pin1", 2, -1, 2, 1, 3, 1) - wing2.addBox("flap2", -7, 0, 1, 6, 1, 6) - wing2.addBox("pin2", -3, -1, 2, 1, 3, 1) - wing3.addBox("flap3", -7, 0, -7, 6, 1, 6) - wing3.addBox("pin3", -3, -1, -3, 1, 3, 1) - - light0.addBox("flap0", 1, 0, -7, 6, 1, 6) - light1.addBox("flap1", 1, 0, 1, 6, 1, 6) - light2.addBox("flap2", -7, 0, 1, 6, 1, 6) - light3.addBox("flap3", -7, 0, -7, 6, 1, 6) - - private val scale = 1 / 16f - private val up = new Vec3d(0, 1, 0) - - private def doRender(drone: Drone, dt: Float) { +import net.minecraft.client.renderer.LightTexture +import net.minecraft.client.renderer.entity.model.EntityModel +import net.minecraft.client.renderer.model.ModelRenderer +import net.minecraft.client.renderer.texture.OverlayTexture +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.util.math.vector.Vector3f + +final class ModelQuadcopter extends EntityModel[Drone] { + val body = new ModelRenderer(this) + val wing0 = new ModelRenderer(this) + val wing1 = new ModelRenderer(this) + val wing2 = new ModelRenderer(this) + val wing3 = new ModelRenderer(this) + val light0 = new ModelRenderer(this) + val light1 = new ModelRenderer(this) + val light2 = new ModelRenderer(this) + val light3 = new ModelRenderer(this) + + texWidth = 64 + texHeight = 32 + + body.texOffs(0, 23).addBox(-3, 1, -3, 6, 1, 6).yRot = math.toRadians(45).toFloat // top + body.texOffs(0, 1).addBox(-1, 0, -1, 2, 1, 2).yRot = math.toRadians(45).toFloat // middle + body.texOffs(0, 17).addBox(-2, -1, -2, 4, 1, 4).yRot = math.toRadians(45).toFloat // bottom + wing0.texOffs(0, 9).addBox(1, 0, -7, 6, 1, 6) // flap0 + wing0.texOffs(0, 27).addBox(2, -1, -3, 1, 3, 1) // pin0 + wing1.texOffs(0, 9).addBox(1, 0, 1, 6, 1, 6) // flap1 + wing1.texOffs(0, 27).addBox(2, -1, 2, 1, 3, 1) // pin1 + wing2.texOffs(0, 9).addBox(-7, 0, 1, 6, 1, 6) // flap2 + wing2.texOffs(0, 27).addBox(-3, -1, 2, 1, 3, 1) // pin2 + wing3.texOffs(0, 9).addBox(-7, 0, -7, 6, 1, 6) // flap3 + wing3.texOffs(0, 27).addBox(-3, -1, -3, 1, 3, 1) // pin3 + + light0.texOffs(24, 0).addBox(1, 0, -7, 6, 1, 6) // flap0 + light1.texOffs(24, 0).addBox(1, 0, 1, 6, 1, 6) // flap1 + light2.texOffs(24, 0).addBox(-7, 0, 1, 6, 1, 6) // flap2 + light3.texOffs(24, 0).addBox(-7, 0, -7, 6, 1, 6) // flap3 + + private val up = new Vector3d(0, 1, 0) + + private def doRender(drone: Drone, dt: Float, stack: MatrixStack, builder: IVertexBuilder, light: Int, overlay: Int, r: Float, g: Float, b: Float, a: Float) { + stack.pushPose() if (drone.isRunning) { val timeJitter = drone.hashCode() ^ 0xFF - GlStateManager.translate(0, (math.sin(timeJitter + (drone.getEntityWorld.getTotalWorldTime + dt) / 20.0) * (1 / 16f)).toFloat, 0) + stack.translate(0, (math.sin(timeJitter + (drone.level.getGameTime + dt) / 20.0) * (1 / 16f)).toFloat, 0) } - val velocity = new Vec3d(drone.motionX, drone.motionY, drone.motionZ) - val direction = velocity.normalize() - if (direction.dotProduct(up) < 0.99) { + val direction = drone.getDeltaMovement.normalize() + if (direction.dot(up) < 0.99) { // Flying sideways. - val rotationAxis = direction.crossProduct(up) - val relativeSpeed = velocity.lengthVector().toFloat / drone.maxVelocity - GlStateManager.rotate(relativeSpeed * -20, rotationAxis.x.toFloat, rotationAxis.y.toFloat, rotationAxis.z.toFloat) + val rotationAxis = direction.cross(up) + val relativeSpeed = drone.getDeltaMovement.length().toFloat / drone.maxVelocity + stack.mulPose(new Vector3f(rotationAxis).rotationDegrees(relativeSpeed * -20)) } - GlStateManager.rotate(drone.bodyAngle, 0, 1, 0) + stack.mulPose(Vector3f.YP.rotationDegrees(drone.bodyAngle)) + body.render(stack, builder, light, overlay, r, g, b, a) - body.render(scale) + wing0.xRot = drone.flapAngles(0)(0) + wing0.zRot = drone.flapAngles(0)(1) + wing1.xRot = drone.flapAngles(1)(0) + wing1.zRot = drone.flapAngles(1)(1) + wing2.xRot = drone.flapAngles(2)(0) + wing2.zRot = drone.flapAngles(2)(1) + wing3.xRot = drone.flapAngles(3)(0) + wing3.zRot = drone.flapAngles(3)(1) - wing0.rotateAngleX = drone.flapAngles(0)(0) - wing0.rotateAngleZ = drone.flapAngles(0)(1) - wing1.rotateAngleX = drone.flapAngles(1)(0) - wing1.rotateAngleZ = drone.flapAngles(1)(1) - wing2.rotateAngleX = drone.flapAngles(2)(0) - wing2.rotateAngleZ = drone.flapAngles(2)(1) - wing3.rotateAngleX = drone.flapAngles(3)(0) - wing3.rotateAngleZ = drone.flapAngles(3)(1) - - wing0.render(scale) - wing1.render(scale) - wing2.render(scale) - wing3.render(scale) + wing0.render(stack, builder, light, overlay, r, g, b, a) + wing1.render(stack, builder, light, overlay, r, g, b, a) + wing2.render(stack, builder, light, overlay, r, g, b, a) + wing3.render(stack, builder, light, overlay, r, g, b, a) if (drone.isRunning) { - RenderState.disableEntityLighting() - GlStateManager.depthFunc(GL11.GL_LEQUAL) - - light0.rotateAngleX = drone.flapAngles(0)(0) - light0.rotateAngleZ = drone.flapAngles(0)(1) - light1.rotateAngleX = drone.flapAngles(1)(0) - light1.rotateAngleZ = drone.flapAngles(1)(1) - light2.rotateAngleX = drone.flapAngles(2)(0) - light2.rotateAngleZ = drone.flapAngles(2)(1) - light3.rotateAngleX = drone.flapAngles(3)(0) - light3.rotateAngleZ = drone.flapAngles(3)(1) - - // Additive blending for the lights. - RenderState.makeItBlend() - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) + light0.xRot = drone.flapAngles(0)(0) + light0.zRot = drone.flapAngles(0)(1) + light1.xRot = drone.flapAngles(1)(0) + light1.zRot = drone.flapAngles(1)(1) + light2.xRot = drone.flapAngles(2)(0) + light2.zRot = drone.flapAngles(2)(1) + light3.xRot = drone.flapAngles(3)(0) + light3.zRot = drone.flapAngles(3)(1) val lightColor = drone.lightColor - val r = (lightColor >>> 16) & 0xFF - val g = (lightColor >>> 8) & 0xFF - val b = (lightColor >>> 0) & 0xFF - GlStateManager.color(r / 255f, g / 255f, b / 255f) - - light0.render(scale) - light1.render(scale) - light2.render(scale) - light3.render(scale) - - RenderState.disableBlend() - RenderState.enableEntityLighting() - GlStateManager.color(1, 1, 1, 1) + val rr = r * ((lightColor >>> 16) & 0xFF) / 255f + val gg = g * ((lightColor >>> 8) & 0xFF) / 255f + val bb = b * ((lightColor >>> 0) & 0xFF) / 255f + val fullLight = LightTexture.pack(15, 15) + + light0.render(stack, builder, fullLight, OverlayTexture.NO_OVERLAY, rr, gg, bb, a) + light1.render(stack, builder, fullLight, OverlayTexture.NO_OVERLAY, rr, gg, bb, a) + light2.render(stack, builder, fullLight, OverlayTexture.NO_OVERLAY, rr, gg, bb, a) + light3.render(stack, builder, fullLight, OverlayTexture.NO_OVERLAY, rr, gg, bb, a) } + stack.popPose() } - // For inventory rendering. - def render() { - body.render(scale) - - val tilt = math.toRadians(2).toFloat - wing0.rotateAngleX = tilt - wing0.rotateAngleZ = tilt - wing1.rotateAngleX = -tilt - wing1.rotateAngleZ = tilt - wing2.rotateAngleX = -tilt - wing2.rotateAngleZ = -tilt - wing3.rotateAngleX = tilt - wing3.rotateAngleZ = -tilt - - wing0.render(scale) - wing1.render(scale) - wing2.render(scale) - wing3.render(scale) - - RenderState.disableEntityLighting() - GlStateManager.depthFunc(GL11.GL_LEQUAL) - - light0.rotateAngleX = tilt - light0.rotateAngleZ = tilt - light1.rotateAngleX = -tilt - light1.rotateAngleZ = tilt - light2.rotateAngleX = -tilt - light2.rotateAngleZ = -tilt - light3.rotateAngleX = tilt - light3.rotateAngleZ = -tilt - - - RenderState.makeItBlend() - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) - GlStateManager.color(0x66 / 255f, 0xDD / 255f, 0x55 / 255f) - - light0.render(scale) - light1.render(scale) - light2.render(scale) - light3.render(scale) - - RenderState.disableBlend() - RenderState.enableEntityLighting() - GlStateManager.color(1, 1, 1, 1) + private var cachedEntity: Drone = null + private var cachedDt = 0.0f + + override def setupAnim(drone: Drone, f1: Float, f2: Float, f3: Float, f4: Float, f5: Float): Unit = {} + + override def prepareMobModel(drone: Drone, f1: Float, f2: Float, dt: Float): Unit = { + cachedEntity = drone + cachedDt = dt } - override def render(entity: Entity, f1: Float, f2: Float, f3: Float, f4: Float, f5: Float, f6: Float): Unit = { - doRender(entity.asInstanceOf[Drone], f6) + override def renderToBuffer(stack: MatrixStack, builder: IVertexBuilder, light: Int, overlay: Int, r: Float, g: Float, b: Float, a: Float): Unit = { + doRender(cachedEntity, cachedDt, stack, builder, light: Int, overlay: Int, r: Float, g: Float, b: Float, a: Float) } } diff --git a/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala index 1e178b7052..109286eb7b 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala @@ -1,14 +1,20 @@ package li.cil.oc.client.renderer.font +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.Settings +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.client.renderer.font.DynamicFontRenderer.CharTexture import li.cil.oc.util.FontUtils import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.resources.IReloadableResourceManager -import net.minecraft.client.resources.IResourceManager -import net.minecraft.client.resources.IResourceManagerReloadListener +import net.minecraft.client.renderer.RenderType +import net.minecraft.client.renderer.texture.TextureUtil +import net.minecraft.resources.IReloadableResourceManager +import net.minecraft.resources.IResourceManager +import net.minecraft.resources.IResourceManagerReloadListener +import net.minecraft.util.math.vector.Matrix4f +import net.minecraft.util.math.vector.Vector4f import org.lwjgl.BufferUtils import org.lwjgl.opengl._ @@ -31,7 +37,7 @@ class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloa initialize() - Minecraft.getMinecraft.getResourceManager match { + Minecraft.getInstance.getResourceManager match { case reloadable: IReloadableResourceManager => reloadable.registerReloadListener(this) case _ => } @@ -42,13 +48,13 @@ class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloa } textures.clear() charMap.clear() + glyphProvider.initialize() textures += new DynamicFontRenderer.CharTexture(this) activeTexture = textures.head generateChars(basicChars.toCharArray) } def onResourceManagerReload(manager: IResourceManager) { - glyphProvider.initialize() initialize() } @@ -64,13 +70,25 @@ class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloa RenderState.checkError(getClass.getName + ".bindTexture") } + override protected def selectType(index: Int): RenderType = { + activeTexture = textures(index) + activeTexture.getType + } + override protected def generateChar(char: Char) { charMap.getOrElseUpdate(char, createCharIcon(char)) } - override protected def drawChar(tx: Float, ty: Float, char: Char) { + override protected def drawChar(matrix: Matrix4f, tx: Float, ty: Float, char: Char) { + charMap.get(char) match { + case Some(icon) if icon.texture == activeTexture => icon.draw(matrix, tx, ty) + case _ => + } + } + + override protected def drawChar(builder: IVertexBuilder, matrix: Matrix4f, color: Int, tx: Float, ty: Float, char: Char) { charMap.get(char) match { - case Some(icon) if icon.texture == activeTexture => icon.draw(tx, ty) + case Some(icon) if icon.texture == activeTexture => icon.draw(builder, matrix, color, tx, ty) case _ => } } @@ -94,17 +112,19 @@ object DynamicFontRenderer { private val size = 256 class CharTexture(val owner: DynamicFontRenderer) { - private val id = GlStateManager.generateTexture() + private val id = TextureUtil.generateTextureId() RenderState.bindTexture(id) if (Settings.get.textLinearFiltering) { GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR) } else { - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST) + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST) } GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST) GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, size, size, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, BufferUtils.createByteBuffer(size * size * 4)) RenderState.bindTexture(0) + private val rt = RenderTypes.createFontTex(id) + RenderState.checkError(getClass.getName + ".: create texture") // Some padding to avoid bleeding. @@ -112,21 +132,23 @@ object DynamicFontRenderer { private val cellHeight = owner.charHeight + 2 private val cols = size / cellWidth private val rows = size / cellHeight - private val uStep = cellWidth / size.toDouble - private val vStep = cellHeight / size.toDouble - private val pad = 1.0 / size + private val uStep = cellWidth / size.toFloat + private val vStep = cellHeight / size.toFloat + private val pad = 1f / size private val capacity = cols * rows private var chars = 0 def delete() { - GlStateManager.deleteTexture(id) + RenderSystem.deleteTexture(id) } def bind() { RenderState.bindTexture(id) } + def getType() = rt + def isFull(char: Char) = chars + FontUtils.wcwidth(char) > capacity def add(char: Char) = { @@ -149,16 +171,34 @@ object DynamicFontRenderer { } } - class CharIcon(val texture: CharTexture, val w: Int, val h: Int, val u1: Double, val v1: Double, val u2: Double, val v2: Double) { - def draw(tx: Float, ty: Float) { - GL11.glTexCoord2d(u1, v2) - GL11.glVertex2f(tx, ty + h) - GL11.glTexCoord2d(u2, v2) - GL11.glVertex2f(tx + w, ty + h) - GL11.glTexCoord2d(u2, v1) - GL11.glVertex2f(tx + w, ty) - GL11.glTexCoord2d(u1, v1) - GL11.glVertex2f(tx, ty) + class CharIcon(val texture: CharTexture, val w: Int, val h: Int, val u1: Float, val v1: Float, val u2: Float, val v2: Float) { + def draw(matrix: Matrix4f, tx: Float, ty: Float) { + GL11.glTexCoord2f(u1, v2) + val vec = new Vector4f(tx, ty + h, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + GL11.glTexCoord2f(u2, v2) + vec.set(tx + w, ty + h, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + GL11.glTexCoord2f(u2, v1) + vec.set(tx + w, ty, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + GL11.glTexCoord2f(u1, v1) + vec.set(tx, ty, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + } + + def draw(builder: IVertexBuilder, matrix: Matrix4f, color: Int, tx: Float, ty: Float) { + val r = ((color >> 16) & 0xFF) / 255f + val g = ((color >> 8) & 0xFF) / 255f + val b = (color & 0xFF) / 255f + builder.vertex(matrix, tx, ty + h, 0).color(r, g, b, 1f).uv(u1, v2).endVertex() + builder.vertex(matrix, tx + w, ty + h, 0).color(r, g, b, 1f).uv(u2, v2).endVertex() + builder.vertex(matrix, tx + w, ty, 0).color(r, g, b, 1f).uv(u2, v1).endVertex() + builder.vertex(matrix, tx, ty, 0).color(r, g, b, 1f).uv(u1, v1).endVertex() } } diff --git a/src/main/scala/li/cil/oc/client/renderer/font/FontParserHex.java b/src/main/scala/li/cil/oc/client/renderer/font/FontParserHex.java index 78eee08440..3a24a6fb69 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/FontParserHex.java +++ b/src/main/scala/li/cil/oc/client/renderer/font/FontParserHex.java @@ -25,7 +25,7 @@ public void initialize() { glyphs[i] = null; } try { - final InputStream font = Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation(Settings.resourceDomain(), "font.hex")).getInputStream(); + final InputStream font = Minecraft.getInstance().getResourceManager().getResource(new ResourceLocation(Settings.resourceDomain(), "font.hex")).getInputStream(); try { OpenComputers.log().info("Initializing unicode glyph provider."); final BufferedReader input = new BufferedReader(new InputStreamReader(font)); diff --git a/src/main/scala/li/cil/oc/client/renderer/font/StaticFontRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/font/StaticFontRenderer.scala index ff3a55f63d..ca0c53c3d6 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/StaticFontRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/font/StaticFontRenderer.scala @@ -1,11 +1,16 @@ package li.cil.oc.client.renderer.font import com.google.common.base.Charsets +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.RenderType import net.minecraft.util.ResourceLocation +import net.minecraft.util.math.vector.Matrix4f +import net.minecraft.util.math.vector.Vector4f import org.lwjgl.opengl.GL11 import scala.io.Source @@ -16,7 +21,7 @@ import scala.io.Source */ class StaticFontRenderer extends TextureFontRenderer { protected val (chars, charWidth, charHeight) = try { - val lines = Source.fromInputStream(Minecraft.getMinecraft.getResourceManager.getResource(new ResourceLocation(Settings.resourceDomain, "textures/font/chars.txt")).getInputStream)(Charsets.UTF_8).getLines() + val lines = Source.fromInputStream(Minecraft.getInstance.getResourceManager.getResource(new ResourceLocation(Settings.resourceDomain, "textures/font/chars.txt")).getInputStream)(Charsets.UTF_8).getLines() val chars = lines.next() val (w, h) = if (lines.hasNext) { val size = lines.next().split(" ", 2) @@ -31,11 +36,11 @@ class StaticFontRenderer extends TextureFontRenderer { } private val cols = 256 / charWidth - private val uStep = charWidth / 256.0 + private val uStep = charWidth / 256f private val uSize = uStep - private val vStep = (charHeight + 1) / 256.0 - private val vSize = charHeight / 256.0 - private val s = Settings.get.fontCharScale + private val vStep = (charHeight + 1) / 256f + private val vSize = charHeight / 256f + private val s = Settings.get.fontCharScale.toFloat private val dw = charWidth * s - charWidth private val dh = charHeight * s - charHeight @@ -48,9 +53,24 @@ class StaticFontRenderer extends TextureFontRenderer { else { Textures.bind(Textures.Font.Aliased) } + if (Settings.get.textLinearFiltering) { + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR) + } + else { + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST) + } + } + + override protected def selectType(index: Int): RenderType = { + if (Settings.get.textAntiAlias) { + RenderTypes.createFontTex("smoothed", Textures.Font.AntiAliased, Settings.get.textLinearFiltering) + } + else { + RenderTypes.createFontTex("aliased", Textures.Font.Aliased, Settings.get.textLinearFiltering) + } } - override protected def drawChar(tx: Float, ty: Float, char: Char) { + override protected def drawChar(matrix: Matrix4f, tx: Float, ty: Float, char: Char) { val index = 1 + (chars.indexOf(char) match { case -1 => chars.indexOf('?') case i => i @@ -60,13 +80,39 @@ class StaticFontRenderer extends TextureFontRenderer { val u = x * uStep val v = y * vStep GL11.glTexCoord2d(u, v + vSize) - GL11.glVertex3d(tx - dw, ty + charHeight * s, 0) + val vec = new Vector4f(tx - dw, ty + charHeight * s, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glTexCoord2d(u + uSize, v + vSize) - GL11.glVertex3d(tx + charWidth * s, ty + charHeight * s, 0) + vec.set(tx + charWidth * s, ty + charHeight * s, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glTexCoord2d(u + uSize, v) - GL11.glVertex3d(tx + charWidth * s, ty - dh, 0) + vec.set(tx + charWidth * s, ty - dh, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glTexCoord2d(u, v) - GL11.glVertex3d(tx - dw, ty - dh, 0) + vec.set(tx - dw, ty - dh, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + } + + protected def drawChar(builder: IVertexBuilder, matrix: Matrix4f, color: Int, tx: Float, ty: Float, char: Char) { + val index = 1 + (chars.indexOf(char) match { + case -1 => chars.indexOf('?') + case i => i + }) + val x = (index - 1) % cols + val y = (index - 1) / cols + val u = x * uStep + val v = y * vStep + val r = ((color >> 16) & 0xFF) / 255f + val g = ((color >> 8) & 0xFF) / 255f + val b = (color & 0xFF) / 255f + builder.vertex(matrix, tx - dw, ty + charHeight * s, 0).color(r, g, b, 1f).uv(u, v + vSize).endVertex() + builder.vertex(matrix, tx + charWidth * s, ty + charHeight * s, 0).color(r, g, b, 1f).uv(u + uSize, v + vSize).endVertex() + builder.vertex(matrix, tx + charWidth * s, ty - dh, 0).color(r, g, b, 1f).uv(u + uSize, v).endVertex() + builder.vertex(matrix, tx - dw, ty - dh, 0).color(r, g, b, 1f).uv(u, v).endVertex() } override protected def generateChar(char: Char) {} diff --git a/src/main/scala/li/cil/oc/client/renderer/font/TextureFontRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/font/TextureFontRenderer.scala index d164830208..47ec494452 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/TextureFontRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/font/TextureFontRenderer.scala @@ -1,10 +1,17 @@ package li.cil.oc.client.renderer.font +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.Settings +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.util.PackedColor import li.cil.oc.util.RenderState import li.cil.oc.util.TextBuffer -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.client.renderer.RenderType +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.util.math.vector.Matrix4f +import net.minecraft.util.math.vector.Vector4f import org.lwjgl.opengl.GL11 /** @@ -26,29 +33,22 @@ abstract class TextureFontRenderer { * be generated inside the draw call. */ def generateChars(chars: Array[Char]) { - GlStateManager.enableTexture2D() + RenderSystem.enableTexture() for (char <- chars) { generateChar(char) } } - def drawBuffer(buffer: TextBuffer, viewportWidth: Int, viewportHeight: Int) { + def drawBuffer(stack: MatrixStack, renderBuff: IRenderTypeBuffer, buffer: TextBuffer, viewportWidth: Int, viewportHeight: Int) { val format = buffer.format - GlStateManager.pushMatrix() - RenderState.pushAttrib() - - GlStateManager.scale(0.5f, 0.5f, 1) + stack.pushPose() - GL11.glDepthMask(false) - RenderState.makeItBlend() - GL11.glDisable(GL11.GL_TEXTURE_2D) - - RenderState.checkError(getClass.getName + ".drawBuffer: configure state") + stack.scale(0.5f, 0.5f, 1) // Background first. We try to merge adjacent backgrounds of the same // color to reduce the number of quads we have to draw. - GL11.glBegin(GL11.GL_QUADS) + var quadBuilder: IVertexBuilder = null for (y <- 0 until (viewportHeight min buffer.height)) { val color = buffer.color(y) var cbg = 0x000000 @@ -56,76 +56,48 @@ abstract class TextureFontRenderer { var width = 0 for (col <- color.map(PackedColor.unpackBackground(_, format)) if x + width < viewportWidth) { if (col != cbg) { - drawQuad(cbg, x, y, width) + if (quadBuilder == null) quadBuilder = renderBuff.getBuffer(RenderTypes.FONT_QUAD) + drawQuad(quadBuilder, stack.last.pose, cbg, x, y, width) cbg = col x += width width = 0 } width = width + 1 } - drawQuad(cbg, x, y, width) - } - GL11.glEnd() - - RenderState.checkError(getClass.getName + ".drawBuffer: background") - - GL11.glEnable(GL11.GL_TEXTURE_2D) - - if (Settings.get.textLinearFiltering) { - GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR) + drawQuad(quadBuilder, stack.last.pose, cbg, x, y, width) } - // Foreground second. We only have to flush when the color changes, so - // unless every char has a different color this should be quite efficient. - for (y <- 0 until (viewportHeight min buffer.height)) { - val line = buffer.buffer(y) - val color = buffer.color(y) - val ty = y * charHeight - for (i <- 0 until textureCount) { - bindTexture(i) - GL11.glBegin(GL11.GL_QUADS) - var cfg = -1 + // Foreground second. We only have to flush when the texture changes. + for (i <- 0 until textureCount) { + // Initialized early because our RenderCache drops empty buffers. + val fontBuilder = renderBuff.getBuffer(selectType(i)) + for (y <- 0 until (viewportHeight min buffer.height)) { + val line = buffer.buffer(y) + val color = buffer.color(y) + val ty = y * charHeight var tx = 0f for (n <- 0 until viewportWidth) { val ch = line(n) - val col = PackedColor.unpackForeground(color(n), format) - // Check if color changed. - if (col != cfg) { - cfg = col - GL11.glColor3f( - ((cfg & 0xFF0000) >> 16) / 255f, - ((cfg & 0x00FF00) >> 8) / 255f, - ((cfg & 0x0000FF) >> 0) / 255f) - } // Don't render whitespace. if (ch != ' ') { - drawChar(tx, ty, ch) + val col = PackedColor.unpackForeground(color(n), format) + drawChar(fontBuilder, stack.last.pose, col, tx, ty, ch) } tx += charWidth } - GL11.glEnd() } } - RenderState.checkError(getClass.getName + ".drawBuffer: foreground") - - GlStateManager.bindTexture(0) - GL11.glDepthMask(true) - GL11.glColor3f(1, 1, 1) - RenderState.disableBlend() - RenderState.popAttrib() - GlStateManager.popMatrix() - - RenderState.checkError(getClass.getName + ".drawBuffer: leaving") + stack.popPose() } - def drawString(s: String, x: Int, y: Int): Unit = { - GlStateManager.pushMatrix() + def drawString(stack: MatrixStack, s: String, x: Int, y: Int): Unit = { + stack.pushPose() RenderState.pushAttrib() - GlStateManager.translate(x, y, 0) - GlStateManager.scale(0.5f, 0.5f, 1) - GlStateManager.depthMask(false) + stack.translate(x, y, 0) + stack.scale(0.5f, 0.5f, 1) + RenderSystem.depthMask(false) for (i <- 0 until textureCount) { bindTexture(i) @@ -135,7 +107,7 @@ abstract class TextureFontRenderer { val ch = s.charAt(n) // Don't render whitespace. if (ch != ' ') { - drawChar(tx, 0, ch) + drawChar(stack.last.pose, tx, 0, ch) } tx += charWidth } @@ -143,8 +115,8 @@ abstract class TextureFontRenderer { } RenderState.popAttrib() - GlStateManager.popMatrix() - GlStateManager.color(1, 1, 1) + stack.popPose() + RenderSystem.color3f(1, 1, 1) } protected def charWidth: Int @@ -155,22 +127,25 @@ abstract class TextureFontRenderer { protected def bindTexture(index: Int): Unit + protected def selectType(index: Int): RenderType + protected def generateChar(char: Char): Unit - protected def drawChar(tx: Float, ty: Float, char: Char): Unit + protected def drawChar(matrix: Matrix4f, tx: Float, ty: Float, char: Char): Unit + + protected def drawChar(builder: IVertexBuilder, matrix: Matrix4f, color: Int, tx: Float, ty: Float, char: Char): Unit - private def drawQuad(color: Int, x: Int, y: Int, width: Int) = if (color != 0 && width > 0) { + private def drawQuad(builder: IVertexBuilder, matrix: Matrix4f, color: Int, x: Int, y: Int, width: Int) = if (color != 0 && width > 0) { val x0 = x * charWidth val x1 = (x + width) * charWidth val y0 = y * charHeight val y1 = (y + 1) * charHeight - GlStateManager.color( - ((color >> 16) & 0xFF) / 255f, - ((color >> 8) & 0xFF) / 255f, - (color & 0xFF) / 255f) - GL11.glVertex3d(x0, y1, 0) - GL11.glVertex3d(x1, y1, 0) - GL11.glVertex3d(x1, y0, 0) - GL11.glVertex3d(x0, y0, 0) + val r = ((color >> 16) & 0xFF) / 255f + val g = ((color >> 8) & 0xFF) / 255f + val b = (color & 0xFF) / 255f + builder.vertex(matrix, x0, y1, 0).color(r, g, b, 1f).endVertex() + builder.vertex(matrix, x1, y1, 0).color(r, g, b, 1f).endVertex() + builder.vertex(matrix, x1, y0, 0).color(r, g, b, 1f).endVertex() + builder.vertex(matrix, x0, y0, 0).color(r, g, b, 1f).endVertex() } } diff --git a/src/main/scala/li/cil/oc/client/renderer/gui/BufferRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/gui/BufferRenderer.scala index 54023d9383..12376b6f59 100644 --- a/src/main/scala/li/cil/oc/client/renderer/gui/BufferRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/gui/BufferRenderer.scala @@ -1,11 +1,14 @@ package li.cil.oc.client.renderer.gui +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.api import li.cil.oc.client.Textures import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GLAllocation -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.texture.TextureManager +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.Tessellator +import net.minecraft.client.renderer.vertex.DefaultVertexFormats +import net.minecraft.util.math.vector.Matrix4f import org.lwjgl.opengl.GL11 object BufferRenderer { @@ -13,103 +16,68 @@ object BufferRenderer { val innerMargin = 1 - private var textureManager: Option[TextureManager] = None - - private var displayLists = 0 - - def init(tm: TextureManager) = this.synchronized(if (textureManager.isEmpty) { - RenderState.checkError(getClass.getName + ".displayLists: entering (aka: wasntme)") - - textureManager = Some(tm) - displayLists = GLAllocation.generateDisplayLists(2) - - RenderState.checkError(getClass.getName + ".displayLists: leaving") - }) - - def compileBackground(bufferWidth: Int, bufferHeight: Int, forRobot: Boolean = false) = - if (textureManager.isDefined) { - RenderState.checkError(getClass.getName + ".compileBackground: entering (aka: wasntme)") - - val innerWidth = innerMargin * 2 + bufferWidth - val innerHeight = innerMargin * 2 + bufferHeight - - GL11.glNewList(displayLists, GL11.GL_COMPILE) - - Textures.bind(Textures.GUI.Borders) - - GL11.glBegin(GL11.GL_QUADS) - - val margin = if (forRobot) 2 else 7 - val (c0, c1, c2, c3) = if (forRobot) (5, 7, 9, 11) else (0, 7, 9, 16) - - // Top border (left corner, middle bar, right corner). - drawBorder( - 0, 0, margin, margin, - c0, c0, c1, c1) - drawBorder( - margin, 0, innerWidth, margin, - c1 + 0.25, c0, c2 - 0.25, c1) - drawBorder( - margin + innerWidth, 0, margin, margin, - c2, c0, c3, c1) - - // Middle area (left bar, screen background, right bar). - drawBorder( - 0, margin, margin, innerHeight, - c0, c1 + 0.25, c1, c2 - 0.25) - drawBorder( - margin, margin, innerWidth, innerHeight, - c1 + 0.25, c1 + 0.25, c2 - 0.25, c2 - 0.25) - drawBorder( - margin + innerWidth, margin, margin, innerHeight, - c2, c1 + 0.25, c3, c2 - 0.25) - - // Bottom border (left corner, middle bar, right corner). - drawBorder( - 0, margin + innerHeight, margin, margin, - c0, c2, c1, c3) - drawBorder( - margin, margin + innerHeight, innerWidth, margin, - c1 + 0.25, c2, c2 - 0.25, c3) - drawBorder( - margin + innerWidth, margin + innerHeight, margin, margin, - c2, c2, c3, c3) - - GL11.glEnd() - - GL11.glEndList() - - RenderState.checkError(getClass.getName + ".compileBackground: leaving") - } - - def drawBackground() = - if (textureManager.isDefined) { - GL11.glCallList(displayLists) - } - - def drawText(screen: api.internal.TextBuffer) = - if (textureManager.isDefined) { - RenderState.pushAttrib() - GlStateManager.depthMask(false) - val changed = screen.renderText() - GlStateManager.depthMask(true) - RenderState.popAttrib() - changed - } - else false + def drawBackground(stack: MatrixStack, bufferWidth: Int, bufferHeight: Int, forRobot: Boolean = false) = { + RenderState.checkError(getClass.getName + ".drawBackground: entering (aka: wasntme)") + + val innerWidth = innerMargin * 2 + bufferWidth + val innerHeight = innerMargin * 2 + bufferHeight + + val t = Tessellator.getInstance + val r = t.getBuilder + Textures.bind(Textures.GUI.Borders) + r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + + val margin = if (forRobot) 2 else 7 + val (c0, c1, c2, c3) = if (forRobot) (5, 7, 9, 11) else (0, 7, 9, 16) + + // Top border (left corner, middle bar, right corner). + drawQuad(stack.last.pose, r, + 0, 0, margin, margin, + c0, c0, c1, c1) + drawQuad(stack.last.pose, r, + margin, 0, innerWidth, margin, + c1 + 0.25f, c0, c2 - 0.25f, c1) + drawQuad(stack.last.pose, r, + margin + innerWidth, 0, margin, margin, + c2, c0, c3, c1) + + // Middle area (left bar, screen background, right bar). + drawQuad(stack.last.pose, r, + 0, margin, margin, innerHeight, + c0, c1 + 0.25f, c1, c2 - 0.25f) + drawQuad(stack.last.pose, r, + margin, margin, innerWidth, innerHeight, + c1 + 0.25f, c1 + 0.25f, c2 - 0.25f, c2 - 0.25f) + drawQuad(stack.last.pose, r, + margin + innerWidth, margin, margin, innerHeight, + c2, c1 + 0.25f, c3, c2 - 0.25f) + + // Bottom border (left corner, middle bar, right corner). + drawQuad(stack.last.pose, r, + 0, margin + innerHeight, margin, margin, + c0, c2, c1, c3) + drawQuad(stack.last.pose, r, + margin, margin + innerHeight, innerWidth, margin, + c1 + 0.25f, c2, c2 - 0.25f, c3) + drawQuad(stack.last.pose, r, + margin + innerWidth, margin + innerHeight, margin, margin, + c2, c2, c3, c3) + + t.end() + + RenderState.checkError(getClass.getName + ".drawBackground: leaving") + } - private def drawBorder(x: Double, y: Double, w: Double, h: Double, u1: Double, v1: Double, u2: Double, v2: Double) = { - val u1d = u1 / 16.0 - val u2d = u2 / 16.0 - val v1d = v1 / 16.0 - val v2d = v2 / 16.0 - GL11.glTexCoord2d(u1d, v2d) - GL11.glVertex3d(x, y + h, 0) - GL11.glTexCoord2d(u2d, v2d) - GL11.glVertex3d(x + w, y + h, 0) - GL11.glTexCoord2d(u2d, v1d) - GL11.glVertex3d(x + w, y, 0) - GL11.glTexCoord2d(u1d, v1d) - GL11.glVertex3d(x, y, 0) + private def drawQuad(matrix: Matrix4f, builder: IVertexBuilder, x: Float, y: Float, w: Float, h: Float, u1: Float, v1: Float, u2: Float, v2: Float) = { + val u1f = u1 / 16f + val u2f = u2 / 16f + val v1f = v1 / 16f + val v2f = v2 / 16f + builder.vertex(matrix, x, y + h, 0).uv(u1f, v2f).endVertex() + builder.vertex(matrix, x + w, y + h, 0).uv(u2f, v2f).endVertex() + builder.vertex(matrix, x+ w, y, 0).uv(u2f, v1f).endVertex() + builder.vertex(matrix, x, y, 0).uv(u1f, v1f).endVertex() } + + def drawText(stack: MatrixStack, screen: api.internal.TextBuffer) = screen.renderText(stack) } diff --git a/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala index 2f5285d164..7ee1b117f6 100644 --- a/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala @@ -1,36 +1,36 @@ package li.cil.oc.client.renderer.item +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.Settings -import li.cil.oc.util.RenderState -import net.minecraft.client.model.ModelBase -import net.minecraft.client.model.ModelBiped -import net.minecraft.client.model.ModelRenderer -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.RenderHelper -import net.minecraft.entity.Entity +import net.minecraft.client.renderer.LightTexture +import net.minecraft.client.renderer.model.Model +import net.minecraft.client.renderer.model.ModelRenderer +import net.minecraft.client.renderer.entity.model.BipedModel +import net.minecraft.client.renderer.texture.OverlayTexture +import net.minecraft.entity.LivingEntity import net.minecraft.util.ResourceLocation -import org.lwjgl.opengl.GL11 -object HoverBootRenderer extends ModelBiped { +object HoverBootRenderer extends BipedModel[LivingEntity](0.5f) { val texture = new ResourceLocation(Settings.resourceDomain, "textures/model/drone.png") - val bootLeft = new ModelRenderer(this, "bootLeft") - val bootRight = new ModelRenderer(this, "bootRight") - val body = new ModelRenderer(this, "body") - val wing0 = new ModelRenderer(this, "wing0") - val wing1 = new ModelRenderer(this, "wing1") - val wing2 = new ModelRenderer(this, "wing2") - val wing3 = new ModelRenderer(this, "wing3") - val light0 = new LightModelRenderer(this, "light0") - val light1 = new LightModelRenderer(this, "light1") - val light2 = new LightModelRenderer(this, "light2") - val light3 = new LightModelRenderer(this, "light3") - - bootLeft.addChild(body) + val bootLeft = new ModelRenderer(this) + val bootRight = new ModelRenderer(this) + val droneBody = new ModelRenderer(this) + val wing0 = new ModelRenderer(this) + val wing1 = new ModelRenderer(this) + val wing2 = new ModelRenderer(this) + val wing3 = new ModelRenderer(this) + val light0 = new LightModelRenderer(this) + val light1 = new LightModelRenderer(this) + val light2 = new LightModelRenderer(this) + val light3 = new LightModelRenderer(this) + + bootLeft.addChild(droneBody) bootLeft.addChild(wing0) bootLeft.addChild(wing1) - bootRight.addChild(body) + bootRight.addChild(droneBody) bootRight.addChild(wing2) bootRight.addChild(wing3) @@ -39,89 +39,59 @@ object HoverBootRenderer extends ModelBiped { wing2.addChild(light2) wing3.addChild(light3) - textureWidth = 64 - textureHeight = 32 - - setTextureOffset("body.middle", 0, 23) - setTextureOffset("body.top", 0, 1) - setTextureOffset("body.bottom", 0, 17) - setTextureOffset("wing0.flap0", 0, 9) - setTextureOffset("wing0.pin0", 0, 27) - setTextureOffset("wing1.flap1", 0, 9) - setTextureOffset("wing1.pin1", 0, 27) - setTextureOffset("wing2.flap2", 0, 9) - setTextureOffset("wing2.pin2", 0, 27) - setTextureOffset("wing3.flap3", 0, 9) - setTextureOffset("wing3.pin3", 0, 27) - - setTextureOffset("light0.flap0", 24, 0) - setTextureOffset("light1.flap1", 24, 0) - setTextureOffset("light2.flap2", 24, 0) - setTextureOffset("light3.flap3", 24, 0) - - bootRight.offsetY = 10.1f / 16 - bootLeft.offsetY = 10.11f / 16f - - body.addBox("top", -3, 1, -3, 6, 1, 6).rotateAngleY = math.toRadians(45).toFloat - body.addBox("middle", -1, 0, -1, 2, 1, 2).rotateAngleY = math.toRadians(45).toFloat - body.addBox("bottom", -2, -1, -2, 4, 1, 4).rotateAngleY = math.toRadians(45).toFloat - wing0.addBox("flap0", -1, 0, -7, 6, 1, 6) - wing0.addBox("pin0", 0, -1, -3, 1, 3, 1) - wing1.addBox("flap1", -1, 0, 1, 6, 1, 6) - wing1.addBox("pin1", 0, -1, 2, 1, 3, 1) - wing2.addBox("flap2", -5, 0, 1, 6, 1, 6) - wing2.addBox("pin2", -1, -1, 2, 1, 3, 1) - wing3.addBox("flap3", -5, 0, -7, 6, 1, 6) - wing3.addBox("pin3", -1, -1, -3, 1, 3, 1) - - light0.addBox("flap0", -1, 0, -7, 6, 1, 6) - light1.addBox("flap1", -1, 0, 1, 6, 1, 6) - light2.addBox("flap2", -5, 0, 1, 6, 1, 6) - light3.addBox("flap3", -5, 0, -7, 6, 1, 6) + texWidth = 64 + texHeight = 32 + + bootRight.y = 10.1f + bootLeft.y = 10.11f + + droneBody.texOffs(0, 23).addBox(-3, 1, -3, 6, 1, 6).yRot = math.toRadians(45).toFloat // top + droneBody.texOffs(0, 1).addBox(-1, 0, -1, 2, 1, 2).yRot = math.toRadians(45).toFloat // middle + droneBody.texOffs(0, 17).addBox(-2, -1, -2, 4, 1, 4).yRot = math.toRadians(45).toFloat // bottom + wing0.texOffs(0, 9).addBox(-1, 0, -7, 6, 1, 6) // flap0 + wing0.texOffs(0, 27).addBox(0, -1, -3, 1, 3, 1) // pin0 + wing1.texOffs(0, 9).addBox(-1, 0, 1, 6, 1, 6) // flap1 + wing1.texOffs(0, 27).addBox(0, -1, 2, 1, 3, 1) // pin1 + wing2.texOffs(0, 9).addBox(-5, 0, 1, 6, 1, 6) // flap2 + wing2.texOffs(0, 27).addBox(-1, -1, 2, 1, 3, 1) // pin2 + wing3.texOffs(0, 9).addBox(-5, 0, -7, 6, 1, 6) // flap3 + wing3.texOffs(0, 27).addBox(-1, -1, -3, 1, 3, 1) // pin3 + + light0.texOffs(24, 0).addBox(-1, 0, -7, 6, 1, 6) // flap0 + light1.texOffs(24, 0).addBox(-1, 0, 1, 6, 1, 6) // flap1 + light2.texOffs(24, 0).addBox(-5, 0, 1, 6, 1, 6) // flap2 + light3.texOffs(24, 0).addBox(-5, 0, -7, 6, 1, 6) // flap3 // No drone textured legs, thank you very much. - bipedLeftLeg.cubeList.clear() - bipedRightLeg.cubeList.clear() + leftLeg = leftLeg.createShallowCopy() + rightLeg = rightLeg.createShallowCopy() - bipedLeftLeg.addChild(bootLeft) - bipedRightLeg.addChild(bootRight) + leftLeg.addChild(bootLeft) + rightLeg.addChild(bootRight) - bipedHead.isHidden = true - bipedHeadwear.isHidden = true - bipedBody.isHidden = true - bipedRightArm.isHidden = true - bipedLeftArm.isHidden = true + head.visible = false + hat.visible = false + body.visible = false + rightArm.visible = false + leftArm.visible = false var lightColor = 0x66DD55 - override def render(entity: Entity, f0: Float, f1: Float, f2: Float, f3: Float, f4: Float, f5: Float): Unit = { + override def setupAnim(entity: LivingEntity, f1: Float, f2: Float, f3: Float, f4: Float, f5: Float): Unit = { + super.setupAnim(entity, f1, f2, f3, f4, f5) // Because Forge is being a dummy... - isSneak = entity.isSneaking + crouching = entity.isCrouching // Because Forge is being an even bigger dummy... - isChild = false - super.render(entity, f0, f1, f2, f3, f4, f5) + young = false } - class LightModelRenderer(modelBase: ModelBase, name: String) extends ModelRenderer(modelBase, name) { - override def render(dt: Float): Unit = { - RenderState.pushAttrib() - GlStateManager.disableLighting() - RenderState.disableEntityLighting() - GlStateManager.depthFunc(GL11.GL_LEQUAL) - RenderState.makeItBlend() - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) - val r = ((lightColor >>> 16) & 0xFF) / 255f - val g = ((lightColor >>> 8) & 0xFF) / 255f - val b = ((lightColor >>> 0) & 0xFF) / 255f - GlStateManager.color(r, g, b) - - super.render(dt) - - RenderState.disableBlend() - GlStateManager.enableLighting() - RenderState.enableEntityLighting() - GlStateManager.color(1, 1, 1) - RenderState.popAttrib() + class LightModelRenderer(modelBase: Model) extends ModelRenderer(modelBase) { + override def render(stack: MatrixStack, builder: IVertexBuilder, light: Int, overlay: Int, r: Float, g: Float, b: Float, a: Float): Unit = { + val rm = ((lightColor >>> 16) & 0xFF) / 255f + val gm = ((lightColor >>> 8) & 0xFF) / 255f + val bm = ((lightColor >>> 0) & 0xFF) / 255f + + super.render(stack, builder, LightTexture.pack(15, 15), OverlayTexture.NO_OVERLAY, r * rm, g * gm, b * bm, a) } } diff --git a/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala index e4dd1512b8..27efacf8e1 100644 --- a/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/item/UpgradeRenderer.scala @@ -1,17 +1,21 @@ package li.cil.oc.client.renderer.item +import com.google.common.collect.ImmutableList +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.Constants import li.cil.oc.api import li.cil.oc.api.driver.item.UpgradeRenderer.MountPointName import li.cil.oc.api.event.RobotRenderEvent.MountPoint -import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.integration.opencomputers.Item import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator +import net.minecraft.client.renderer.IRenderTypeBuffer import net.minecraft.client.renderer.vertex.DefaultVertexFormats +import net.minecraft.client.renderer.vertex.VertexFormat import net.minecraft.item.ItemStack -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.util.math.vector.Vector3f import org.lwjgl.opengl.GL11 object UpgradeRenderer { @@ -36,71 +40,63 @@ object UpgradeRenderer { descriptor == craftingUpgrade || descriptor == generatorUpgrade || descriptor == inventoryUpgrade } - def render(stack: ItemStack, mountPoint: MountPoint): Unit = { + def render(matrix: MatrixStack, buffer: IRenderTypeBuffer, stack: ItemStack, mountPoint: MountPoint): Unit = { val descriptor = api.Items.get(stack) if (descriptor == api.Items.get(Constants.ItemName.CraftingUpgrade)) { - Textures.bind(Textures.Model.UpgradeCrafting) - drawSimpleBlock(mountPoint) + drawSimpleBlock(matrix, buffer.getBuffer(RenderTypes.UPGRADE_CRAFTING), mountPoint) RenderState.checkError(getClass.getName + ".renderItem: crafting upgrade") } else if (descriptor == api.Items.get(Constants.ItemName.GeneratorUpgrade)) { - Textures.bind(Textures.Model.UpgradeGenerator) - drawSimpleBlock(mountPoint, if (Item.dataTag(stack).getInteger("remainingTicks") > 0) 0.5f else 0) + drawSimpleBlock(matrix, buffer.getBuffer(RenderTypes.UPGRADE_GENERATOR), mountPoint, if (Item.dataTag(stack).getInt("remainingTicks") > 0) 0.5f else 0) RenderState.checkError(getClass.getName + ".renderItem: generator upgrade") } else if (descriptor == api.Items.get(Constants.ItemName.InventoryUpgrade)) { - Textures.bind(Textures.Model.UpgradeInventory) - drawSimpleBlock(mountPoint) + drawSimpleBlock(matrix, buffer.getBuffer(RenderTypes.UPGRADE_INVENTORY), mountPoint) RenderState.checkError(getClass.getName + ".renderItem: inventory upgrade") } } - private val bounds = new AxisAlignedBB(-0.1, -0.1, -0.1, 0.1, 0.1, 0.1) + private val (minX, minY, minZ) = (-0.1f, -0.1f, -0.1f) + private val (maxX, maxY, maxZ) = (0.1f, 0.1f, 0.1f) - private def drawSimpleBlock(mountPoint: MountPoint, frontOffset: Float = 0) { - GlStateManager.rotate(mountPoint.rotation.getW, mountPoint.rotation.getX, mountPoint.rotation.getY, mountPoint.rotation.getZ) - GlStateManager.translate(mountPoint.offset.getX, mountPoint.offset.getY, mountPoint.offset.getZ) - - val t = Tessellator.getInstance() - val r = t.getBuffer - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_NORMAL) + private def drawSimpleBlock(stack: MatrixStack, r: IVertexBuilder, mountPoint: MountPoint, frontOffset: Float = 0) { + stack.mulPose(new Vector3f(mountPoint.rotation.x, mountPoint.rotation.y, mountPoint.rotation.z).rotationDegrees(mountPoint.rotation.w)) + stack.translate(mountPoint.offset.x, mountPoint.offset.y, mountPoint.offset.z) // Front. - r.pos(bounds.minX, bounds.minY, bounds.maxZ).tex(frontOffset, 0.5f).normal(0, 0, 1).endVertex() - r.pos(bounds.maxX, bounds.minY, bounds.maxZ).tex(frontOffset + 0.5f, 0.5f).normal(0, 0, 1).endVertex() - r.pos(bounds.maxX, bounds.maxY, bounds.maxZ).tex(frontOffset + 0.5f, 0).normal(0, 0, 1).endVertex() - r.pos(bounds.minX, bounds.maxY, bounds.maxZ).tex(frontOffset, 0).normal(0, 0, 1).endVertex() + r.vertex(stack.last.pose, minX, minY, maxZ).uv(frontOffset, 0.5f).normal(stack.last.normal, 0, 0, 1).endVertex() + r.vertex(stack.last.pose, maxX, minY, maxZ).uv(frontOffset + 0.5f, 0.5f).normal(stack.last.normal, 0, 0, 1).endVertex() + r.vertex(stack.last.pose, maxX, maxY, maxZ).uv(frontOffset + 0.5f, 0).normal(stack.last.normal, 0, 0, 1).endVertex() + r.vertex(stack.last.pose, minX, maxY, maxZ).uv(frontOffset, 0).normal(stack.last.normal, 0, 0, 1).endVertex() // Top. - r.pos(bounds.maxX, bounds.maxY, bounds.maxZ).tex(1, 0.5f).normal(0, 1, 0).endVertex() - r.pos(bounds.maxX, bounds.maxY, bounds.minZ).tex(1, 1).normal(0, 1, 0).endVertex() - r.pos(bounds.minX, bounds.maxY, bounds.minZ).tex(0.5f, 1).normal(0, 1, 0).endVertex() - r.pos(bounds.minX, bounds.maxY, bounds.maxZ).tex(0.5f, 0.5f).normal(0, 1, 0).endVertex() + r.vertex(stack.last.pose, maxX, maxY, maxZ).uv(1, 0.5f).normal(stack.last.normal, 0, 1, 0).endVertex() + r.vertex(stack.last.pose, maxX, maxY, minZ).uv(1, 1).normal(stack.last.normal, 0, 1, 0).endVertex() + r.vertex(stack.last.pose, minX, maxY, minZ).uv(0.5f, 1).normal(stack.last.normal, 0, 1, 0).endVertex() + r.vertex(stack.last.pose, minX, maxY, maxZ).uv(0.5f, 0.5f).normal(stack.last.normal, 0, 1, 0).endVertex() // Bottom. - r.pos(bounds.minX, bounds.minY, bounds.maxZ).tex(0.5f, 0.5f).normal(0, -1, 0).endVertex() - r.pos(bounds.minX, bounds.minY, bounds.minZ).tex(0.5f, 1).normal(0, -1, 0).endVertex() - r.pos(bounds.maxX, bounds.minY, bounds.minZ).tex(1, 1).normal(0, -1, 0).endVertex() - r.pos(bounds.maxX, bounds.minY, bounds.maxZ).tex(1, 0.5f).normal(0, -1, 0).endVertex() + r.vertex(stack.last.pose, minX, minY, maxZ).uv(0.5f, 0.5f).normal(stack.last.normal, 0, -1, 0).endVertex() + r.vertex(stack.last.pose, minX, minY, minZ).uv(0.5f, 1).normal(stack.last.normal, 0, -1, 0).endVertex() + r.vertex(stack.last.pose, maxX, minY, minZ).uv(1, 1).normal(stack.last.normal, 0, -1, 0).endVertex() + r.vertex(stack.last.pose, maxX, minY, maxZ).uv(1, 0.5f).normal(stack.last.normal, 0, -1, 0).endVertex() // Left. - r.pos(bounds.maxX, bounds.maxY, bounds.maxZ).tex(0, 0.5f).normal(1, 0, 0).endVertex() - r.pos(bounds.maxX, bounds.minY, bounds.maxZ).tex(0, 1).normal(1, 0, 0).endVertex() - r.pos(bounds.maxX, bounds.minY, bounds.minZ).tex(0.5f, 1).normal(1, 0, 0).endVertex() - r.pos(bounds.maxX, bounds.maxY, bounds.minZ).tex(0.5f, 0.5f).normal(1, 0, 0).endVertex() + r.vertex(stack.last.pose, maxX, maxY, maxZ).uv(0, 0.5f).normal(stack.last.normal, 1, 0, 0).endVertex() + r.vertex(stack.last.pose, maxX, minY, maxZ).uv(0, 1).normal(stack.last.normal, 1, 0, 0).endVertex() + r.vertex(stack.last.pose, maxX, minY, minZ).uv(0.5f, 1).normal(stack.last.normal, 1, 0, 0).endVertex() + r.vertex(stack.last.pose, maxX, maxY, minZ).uv(0.5f, 0.5f).normal(stack.last.normal, 1, 0, 0).endVertex() // Right. - r.pos(bounds.minX, bounds.minY, bounds.maxZ).tex(0, 1).normal(-1, 0, 0).endVertex() - r.pos(bounds.minX, bounds.maxY, bounds.maxZ).tex(0, 0.5f).normal(-1, 0, 0).endVertex() - r.pos(bounds.minX, bounds.maxY, bounds.minZ).tex(0.5f, 0.5f).normal(-1, 0, 0).endVertex() - r.pos(bounds.minX, bounds.minY, bounds.minZ).tex(0.5f, 1).normal(-1, 0, 0).endVertex() - - t.draw() + r.vertex(stack.last.pose, minX, minY, maxZ).uv(0, 1).normal(stack.last.normal, -1, 0, 0).endVertex() + r.vertex(stack.last.pose, minX, maxY, maxZ).uv(0, 0.5f).normal(stack.last.normal, -1, 0, 0).endVertex() + r.vertex(stack.last.pose, minX, maxY, minZ).uv(0.5f, 0.5f).normal(stack.last.normal, -1, 0, 0).endVertex() + r.vertex(stack.last.pose, minX, minY, minZ).uv(0.5f, 1).normal(stack.last.normal, -1, 0, 0).endVertex() } } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala index 82ca004ff6..9ecea144b0 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/Document.scala @@ -1,12 +1,14 @@ package li.cil.oc.client.renderer.markdown +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.api import li.cil.oc.client.renderer.markdown.segment.InteractiveSegment import li.cil.oc.client.renderer.markdown.segment.Segment import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft import net.minecraft.client.gui.FontRenderer -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.util.math.vector.Vector4f import org.lwjgl.opengl.GL11 import scala.collection.Iterable @@ -61,45 +63,32 @@ object Document { /** * Line height for a normal line of text. */ - def lineHeight(renderer: FontRenderer): Int = renderer.FONT_HEIGHT + 1 + def lineHeight(renderer: FontRenderer): Int = renderer.lineHeight + 1 /** * Renders a list of segments and tooltips if a segment with a tooltip is hovered. * Returns the hovered interactive segment, if any. */ - def render(document: Segment, x: Int, y: Int, maxWidth: Int, maxHeight: Int, yOffset: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { - val mc = Minecraft.getMinecraft + def render(stack: MatrixStack, document: Segment, x: Int, y: Int, maxWidth: Int, maxHeight: Int, yOffset: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + val window = Minecraft.getInstance.getWindow RenderState.pushAttrib() - // On some systems/drivers/graphics cards the next calls won't update the - // depth buffer correctly if alpha test is enabled. Guess how we found out? - // By noticing that on those systems it only worked while chat messages - // were visible. Yeah. I know. - GlStateManager.disableAlpha() - - // Clear depth mask, then create masks in foreground above and below scroll area. - GlStateManager.color(1, 1, 1, 1) - GlStateManager.clear(GL11.GL_DEPTH_BUFFER_BIT) - GlStateManager.enableDepth() - GlStateManager.depthFunc(GL11.GL_LEQUAL) - GlStateManager.depthMask(true) - GlStateManager.colorMask(false, false, false, false) - - GlStateManager.pushMatrix() - GlStateManager.translate(0, 0, 500) - GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex2f(0, y) - GL11.glVertex2f(mc.displayWidth, y) - GL11.glVertex2f(mc.displayWidth, 0) - GL11.glVertex2f(0, 0) - GL11.glVertex2f(0, mc.displayHeight) - GL11.glVertex2f(mc.displayWidth, mc.displayHeight) - GL11.glVertex2f(mc.displayWidth, y + maxHeight) - GL11.glVertex2f(0, y + maxHeight) - GL11.glEnd() - GlStateManager.popMatrix() - GlStateManager.colorMask(true, true, true, true) + RenderSystem.color4f(1, 1, 1, 1) + // Clip using the scissor test to not interfere with RenderType-maintained depth testing. + GL11.glEnable(GL11.GL_SCISSOR_TEST) + val (x0, y0, x1, y1) = { + val scale = window.getGuiScale + val bottomLeft = new Vector4f(x, y + maxHeight, 0, 1) + bottomLeft.transform(stack.last.pose) + val topRight = new Vector4f(x + maxWidth, y, 0, 1) + topRight.transform(stack.last.pose) + ((bottomLeft.x * scale).floor.asInstanceOf[Int], + (window.getHeight - bottomLeft.y * scale).floor.asInstanceOf[Int], + (topRight.x * scale).ceil.asInstanceOf[Int], + (window.getHeight - topRight.y * scale).ceil.asInstanceOf[Int]) + } + GL11.glScissor(x0, y0, x1 - x0, y1 - y0); // Actual rendering. var hovered: Option[InteractiveSegment] = None @@ -111,7 +100,7 @@ object Document { while (segment != null) { val segmentHeight = segment.nextY(indent, maxWidth, renderer) if (currentY + segmentHeight >= minY && currentY <= maxY) { - val result = segment.render(x, currentY, indent, maxWidth, renderer, mouseX, mouseY) + val result = segment.render(stack, x, currentY, indent, maxWidth, renderer, mouseX, mouseY) hovered = hovered.orElse(result) } currentY += segmentHeight @@ -121,8 +110,7 @@ object Document { if (mouseX < x || mouseX > x + maxWidth || mouseY < y || mouseY > y + maxHeight) hovered = None hovered.foreach(_.notifyHover()) - RenderState.popAttrib() - GlStateManager.bindTexture(0) + GL11.glDisable(GL11.GL_SCISSOR_TEST) hovered } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala index 365577fe4a..c7a094e00d 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/BasicTextSegment.scala @@ -78,5 +78,5 @@ trait BasicTextSegment extends Segment { pos } - protected def computeWrapIndent(renderer: FontRenderer) = if (lists.contains(rootPrefix)) renderer.getStringWidth(rootPrefix) else 0 + protected def computeWrapIndent(renderer: FontRenderer) = if (lists.contains(rootPrefix)) renderer.width(rootPrefix) else 0 } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala index 692019483f..9b63146654 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/CodeSegment.scala @@ -1,12 +1,13 @@ package li.cil.oc.client.renderer.markdown.segment +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.renderer.TextBufferRenderCache import li.cil.oc.client.renderer.markdown.MarkupFormat import net.minecraft.client.gui.FontRenderer -import net.minecraft.client.renderer.GlStateManager private[markdown] class CodeSegment(val parent: Segment, val text: String) extends BasicTextSegment { - override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + override def render(stack: MatrixStack, x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { TextBufferRenderCache.renderer.generateChars(text.toCharArray) var currentX = x + indent @@ -16,8 +17,8 @@ private[markdown] class CodeSegment(val parent: Segment, val text: String) exten var numChars = maxChars(chars, maxWidth - indent, maxWidth - wrapIndent, renderer) while (chars.length > 0) { val part = chars.take(numChars) - GlStateManager.color(0.75f, 0.8f, 1, 1) - TextBufferRenderCache.renderer.drawString(part, currentX, currentY) + RenderSystem.color4f(0.75f, 0.8f, 1, 1) + TextBufferRenderCache.renderer.drawString(stack, part, currentX, currentY) currentX = x + wrapIndent currentY += lineHeight(renderer) chars = chars.drop(numChars).dropWhile(_.isWhitespace) diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala index 84af300415..c105849cc3 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/LinkSegment.scala @@ -8,6 +8,7 @@ import li.cil.oc.api import li.cil.oc.client.Manual import li.cil.oc.client.renderer.markdown.MarkupFormat import net.minecraft.client.Minecraft +import net.minecraft.util.Util private[markdown] class LinkSegment(parent: Segment, text: String, val url: String) extends TextSegment(parent, text) with InteractiveSegment { private final val normalColor = 0x66FF66 @@ -52,7 +53,7 @@ private[markdown] class LinkSegment(parent: Segment, text: String, val url: Stri desktop.getMethod("browse", classOf[URI]).invoke(instance, new URI(url)) } catch { - case t: Throwable => Minecraft.getMinecraft.player.sendMessage(Localization.Chat.WarningLink(t.toString)) + case t: Throwable => Minecraft.getInstance.player.sendMessage(Localization.Chat.WarningLink(t.toString), Util.NIL_UUID) } } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala index 4f484c3548..d8ace50bc5 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/RenderSegment.scala @@ -1,11 +1,14 @@ package li.cil.oc.client.renderer.markdown.segment +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.api.manual.ImageRenderer import li.cil.oc.api.manual.InteractiveImageRenderer import li.cil.oc.client.renderer.markdown.Document import li.cil.oc.client.renderer.markdown.MarkupFormat import net.minecraft.client.gui.FontRenderer -import net.minecraft.client.renderer.GlStateManager +import net.minecraft.util.math.vector.Matrix4f +import net.minecraft.util.math.vector.Vector4f import org.lwjgl.opengl.GL11 private[markdown] class RenderSegment(val parent: Segment, val title: String, val imageRenderer: ImageRenderer) extends InteractiveSegment { @@ -32,7 +35,7 @@ private[markdown] class RenderSegment(val parent: Segment, val title: String, va override def nextX(indent: Int, maxWidth: Int, renderer: FontRenderer): Int = 0 - override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + override def render(stack: MatrixStack, x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { val width = imageWidth(maxWidth) val height = imageHeight(maxWidth) val xOffset = (maxWidth - width) / 2 @@ -44,34 +47,45 @@ private[markdown] class RenderSegment(val parent: Segment, val title: String, va val hovered = checkHovered(mouseX, mouseY, x + xOffset, y + yOffset, width, height) - GlStateManager.pushMatrix() - GlStateManager.translate(x + xOffset, y + yOffset, 0) - GlStateManager.scale(s, s, s) + stack.pushPose() + stack.translate(x + xOffset, y + yOffset, 0) + stack.scale(s, s, s) - GlStateManager.enableBlend() - GlStateManager.enableAlpha() + RenderSystem.enableBlend() + RenderSystem.enableAlphaTest() + // Disabled by text rendering above it (default state is disabled). + RenderSystem.enableDepthTest() if (hovered.isDefined) { - GlStateManager.color(1, 1, 1, 0.15f) - GlStateManager.disableTexture2D() + RenderSystem.color4f(1, 1, 1, 0.15f) + RenderSystem.disableTexture() GL11.glBegin(GL11.GL_QUADS) - GL11.glVertex2f(0, 0) - GL11.glVertex2f(0, imageRenderer.getHeight) - GL11.glVertex2f(imageRenderer.getWidth, imageRenderer.getHeight) - GL11.glVertex2f(imageRenderer.getWidth, 0) + val matrix = stack.last.pose + val vec = new Vector4f(0, 0, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + vec.set(0, imageRenderer.getHeight, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + vec.set(imageRenderer.getWidth, imageRenderer.getHeight, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) + vec.set(imageRenderer.getWidth, 0, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glEnd() - GlStateManager.enableTexture2D() + RenderSystem.enableTexture() } - GlStateManager.color(1, 1, 1, 1) + RenderSystem.color4f(1, 1, 1, 1) - imageRenderer.render(mouseX - x, mouseY - y) + imageRenderer.render(stack, mouseX - x, mouseY - y) - GlStateManager.disableBlend() - GlStateManager.disableAlpha() - GlStateManager.disableLighting() + RenderSystem.disableBlend() + RenderSystem.disableAlphaTest() + RenderSystem.disableLighting() - GlStateManager.popMatrix() + stack.popPose() hovered } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala index 645dd1a90a..13a4b59052 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/Segment.scala @@ -1,5 +1,6 @@ package li.cil.oc.client.renderer.markdown.segment +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.client.renderer.markdown.MarkupFormat import net.minecraft.client.gui.FontRenderer @@ -46,7 +47,7 @@ trait Segment { * Render the segment at the specified coordinates with the specified * properties. */ - def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = None + def render(stack: MatrixStack, x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = None def renderAsText(format: MarkupFormat.Value): Iterable[String] = { var segment = this diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala index f89032ba5e..b47ad92679 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/TextSegment.scala @@ -1,15 +1,16 @@ package li.cil.oc.client.renderer.markdown.segment +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.renderer.markdown.Document import net.minecraft.client.gui.FontRenderer -import net.minecraft.client.renderer.GlStateManager import org.lwjgl.opengl.GL11 import scala.collection.mutable import scala.util.matching.Regex private[markdown] class TextSegment(val parent: Segment, val text: String) extends BasicTextSegment { - override def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { + override def render(stack: MatrixStack, x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = { var currentX = x + indent var currentY = y var chars = text @@ -20,12 +21,12 @@ private[markdown] class TextSegment(val parent: Segment, val text: String) exten while (chars.length > 0) { val part = chars.take(numChars) hovered = hovered.orElse(resolvedInteractive.fold(None: Option[InteractiveSegment])(_.checkHovered(mouseX, mouseY, currentX, currentY, stringWidth(part, renderer), (Document.lineHeight(renderer) * resolvedScale).toInt))) - GlStateManager.pushMatrix() - GlStateManager.translate(currentX, currentY, 0) - GlStateManager.scale(resolvedScale, resolvedScale, resolvedScale) - GlStateManager.translate(-currentX, -currentY, 0) - renderer.drawString(resolvedFormat + part, currentX, currentY, resolvedColor) - GlStateManager.popMatrix() + stack.pushPose() + stack.translate(currentX, currentY, 0) + stack.scale(resolvedScale, resolvedScale, resolvedScale) + stack.translate(-currentX, -currentY, 0) + renderer.draw(stack, resolvedFormat + part, currentX, currentY, resolvedColor) + stack.popPose() currentX = x + wrapIndent currentY += lineHeight(renderer) chars = chars.drop(numChars).dropWhile(_.isWhitespace) @@ -65,7 +66,7 @@ private[markdown] class TextSegment(val parent: Segment, val text: String) exten override protected def lineHeight(renderer: FontRenderer): Int = (super.lineHeight(renderer) * resolvedScale).toInt - override protected def stringWidth(s: String, renderer: FontRenderer): Int = (renderer.getStringWidth(resolvedFormat + s) * resolvedScale).toInt + override protected def stringWidth(s: String, renderer: FontRenderer): Int = (renderer.width(resolvedFormat + s) * resolvedScale).toInt // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/BlockImageProvider.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/BlockImageProvider.scala index 8314464fc9..7329e253e0 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/BlockImageProvider.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/BlockImageProvider.scala @@ -1,23 +1,18 @@ package li.cil.oc.client.renderer.markdown.segment.render -import com.google.common.base.Strings import li.cil.oc.api.manual.ImageProvider import li.cil.oc.api.manual.ImageRenderer import li.cil.oc.api.manual.InteractiveImageRenderer -import li.cil.oc.client.Textures import net.minecraft.block.Block -import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation +import net.minecraftforge.registries.ForgeRegistries object BlockImageProvider extends ImageProvider { override def getImage(data: String): ImageRenderer = { - val splitIndex = data.lastIndexOf('@') - val (name, optMeta) = if (splitIndex > 0) data.splitAt(splitIndex) else (data, "") - val meta = if (Strings.isNullOrEmpty(optMeta)) 0 else Integer.parseInt(optMeta.drop(1)) - Block.REGISTRY.getObject(new ResourceLocation(name)) match { - case block: Block if Item.getItemFromBlock(block) != null => new ItemStackImageRenderer(Array(new ItemStack(block, 1, meta))) - case _ => new TextureImageRenderer(Textures.GUI.ManualMissingItem) with InteractiveImageRenderer { + ForgeRegistries.BLOCKS.getValue(new ResourceLocation(data.toLowerCase)) match { + case block: Block if block.asItem() != null => new ItemStackImageRenderer(Array(new ItemStack(block))) + case _ => new TextureImageRenderer(TextureImageProvider.ManualMissingItem) with InteractiveImageRenderer { override def getTooltip(tooltip: String): String = "oc:gui.Manual.Warning.BlockMissing" override def onMouseClick(mouseX: Int, mouseY: Int): Boolean = false diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemImageProvider.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemImageProvider.scala index f0ae718de0..9c3ebacec7 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemImageProvider.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemImageProvider.scala @@ -1,22 +1,18 @@ package li.cil.oc.client.renderer.markdown.segment.render -import com.google.common.base.Strings import li.cil.oc.api.manual.ImageProvider import li.cil.oc.api.manual.ImageRenderer import li.cil.oc.api.manual.InteractiveImageRenderer -import li.cil.oc.client.Textures import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation +import net.minecraftforge.registries.ForgeRegistries object ItemImageProvider extends ImageProvider { override def getImage(data: String): ImageRenderer = { - val splitIndex = data.lastIndexOf('@') - val (name, optMeta) = if (splitIndex > 0) data.splitAt(splitIndex) else (data, "") - val meta = if (Strings.isNullOrEmpty(optMeta)) 0 else Integer.parseInt(optMeta.drop(1)) - Item.REGISTRY.getObject(new ResourceLocation(name)) match { - case item: Item => new ItemStackImageRenderer(Array(new ItemStack(item, 1, meta))) - case _ => new TextureImageRenderer(Textures.GUI.ManualMissingItem) with InteractiveImageRenderer { + ForgeRegistries.ITEMS.getValue(new ResourceLocation(data.toLowerCase)) match { + case item: Item => new ItemStackImageRenderer(Array(new ItemStack(item))) + case _ => new TextureImageRenderer(TextureImageProvider.ManualMissingItem) with InteractiveImageRenderer { override def getTooltip(tooltip: String): String = "oc:gui.Manual.Warning.ItemMissing" override def onMouseClick(mouseX: Int, mouseY: Int): Boolean = false diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemStackImageRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemStackImageRenderer.scala index 277591b0ff..cb334056a5 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemStackImageRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/ItemStackImageRenderer.scala @@ -1,13 +1,14 @@ package li.cil.oc.client.renderer.markdown.segment.render +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.api.manual.ImageRenderer import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.OpenGlHelper import net.minecraft.client.renderer.RenderHelper import net.minecraft.item.ItemStack import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL12 +import org.lwjgl.opengl.GL13 private[markdown] class ItemStackImageRenderer(val stacks: Array[ItemStack]) extends ImageRenderer { // How long to show individual stacks, in milliseconds, before switching to the next. @@ -17,16 +18,18 @@ private[markdown] class ItemStackImageRenderer(val stacks: Array[ItemStack]) ext override def getHeight = 32 - override def render(mouseX: Int, mouseY: Int): Unit = { - val mc = Minecraft.getMinecraft + override def render(matrix: MatrixStack, mouseX: Int, mouseY: Int): Unit = { + val mc = Minecraft.getInstance val index = (System.currentTimeMillis() % (cycleSpeed * stacks.length)).toInt / cycleSpeed val stack = stacks(index) - GlStateManager.scale(getWidth / 16, getHeight / 16, getWidth / 16) - GlStateManager.enableRescaleNormal() - RenderHelper.enableGUIStandardItemLighting() - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240) - mc.getRenderItem.renderItemAndEffectIntoGUI(stack, 0, 0) - RenderHelper.disableStandardItemLighting() + matrix.scale(getWidth / 16, getHeight / 16, getWidth / 16) + // Translate manually because ItemRenderer generally can't take a MatrixStack. + RenderSystem.pushMatrix() + RenderSystem.multMatrix(matrix.last().pose()) + RenderSystem.enableRescaleNormal() + RenderSystem.glMultiTexCoord2f(GL13.GL_TEXTURE1, 240, 240) + mc.getItemRenderer.renderAndDecorateItem(stack, 0, 0) + RenderSystem.popMatrix() } } diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/OreDictImageProvider.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/OreDictImageProvider.scala index 0bad3914f9..220ef8358c 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/OreDictImageProvider.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/OreDictImageProvider.scala @@ -4,15 +4,31 @@ import li.cil.oc.api.manual.ImageProvider import li.cil.oc.api.manual.ImageRenderer import li.cil.oc.api.manual.InteractiveImageRenderer import li.cil.oc.client.Textures -import net.minecraftforge.oredict.OreDictionary +import net.minecraft.block.Block +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.tags._ +import net.minecraft.util.ResourceLocation -import scala.collection.convert.WrapAsScala._ +import scala.collection.mutable +import scala.collection.convert.ImplicitConversionsToScala._ object OreDictImageProvider extends ImageProvider { override def getImage(data: String): ImageRenderer = { - val stacks = OreDictionary.getOres(data).filter(stack => !stack.isEmpty && stack.getItem != null) - if (stacks != null && stacks.nonEmpty) new ItemStackImageRenderer(stacks.toArray) - else new TextureImageRenderer(Textures.GUI.ManualMissingItem) with InteractiveImageRenderer { + val desired = new ResourceLocation(data.toLowerCase) + val stacks = mutable.ArrayBuffer.empty[ItemStack] + ItemTags.getAllTags.getTag(desired) match { + case tag: ITag[Item] => stacks ++= tag.getValues.map(new ItemStack(_)) + case _ => + } + if (stacks.isEmpty) { + BlockTags.getAllTags.getTag(desired) match { + case tag: ITag[Block] => stacks ++= tag.getValues.map(new ItemStack(_)) + case _ => + } + } + if (stacks.nonEmpty) new ItemStackImageRenderer(stacks.toArray) + else new TextureImageRenderer(TextureImageProvider.ManualMissingItem) with InteractiveImageRenderer { override def getTooltip(tooltip: String): String = "oc:gui.Manual.Warning.OreDictMissing" override def onMouseClick(mouseX: Int, mouseY: Int): Boolean = false diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala index 588c81bd76..9491f9f3c2 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageProvider.scala @@ -7,9 +7,14 @@ import li.cil.oc.client.Textures import net.minecraft.util.ResourceLocation object TextureImageProvider extends ImageProvider { + val ManualMissingItem = { + val tex = Textures.GUI.ManualMissingItem + new ResourceLocation(tex.getNamespace, s"textures/${tex.getPath}.png") + } + override def getImage(data: String): ImageRenderer = { - try new TextureImageRenderer(new ResourceLocation(data)) catch { - case t: Throwable => new TextureImageRenderer(Textures.GUI.ManualMissingItem) with InteractiveImageRenderer { + try new TextureImageRenderer(new ResourceLocation(data.toLowerCase)) catch { + case t: Throwable => new TextureImageRenderer(ManualMissingItem) with InteractiveImageRenderer { override def getTooltip(tooltip: String): String = "oc:gui.Manual.Warning.ImageMissing" override def onMouseClick(mouseX: Int, mouseY: Int): Boolean = false diff --git a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageRenderer.scala index 4af762c091..77b1e9a58d 100644 --- a/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/markdown/segment/render/TextureImageRenderer.scala @@ -3,27 +3,29 @@ package li.cil.oc.client.renderer.markdown.segment.render import java.io.InputStream import javax.imageio.ImageIO +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.api.manual.ImageRenderer import li.cil.oc.client.Textures import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.texture.AbstractTexture +import net.minecraft.client.renderer.texture.Texture import net.minecraft.client.renderer.texture.TextureUtil -import net.minecraft.client.resources.IResourceManager +import net.minecraft.resources.IResourceManager import net.minecraft.util.ResourceLocation +import net.minecraft.util.math.vector.Matrix4f +import net.minecraft.util.math.vector.Vector4f import org.lwjgl.opengl.GL11 +import org.lwjgl.system.MemoryUtil class TextureImageRenderer(val location: ResourceLocation) extends ImageRenderer { private val texture = { - val manager = Minecraft.getMinecraft.getTextureManager + val manager = Minecraft.getInstance.getTextureManager manager.getTexture(location) match { case image: ImageTexture => image case other => - if (other != null && other.getGlTextureId != -1) { - TextureUtil.deleteTexture(other.getGlTextureId) - } + if (other != null) other.releaseId() val image = new ImageTexture(location) - manager.loadTexture(location, image) + manager.register(location, image) image } } @@ -32,34 +34,54 @@ class TextureImageRenderer(val location: ResourceLocation) extends ImageRenderer override def getHeight: Int = texture.height - override def render(mouseX: Int, mouseY: Int): Unit = { + override def render(stack: MatrixStack, mouseX: Int, mouseY: Int): Unit = { Textures.bind(location) - GlStateManager.color(1, 1, 1, 1) + RenderSystem.color4f(1, 1, 1, 1) GL11.glBegin(GL11.GL_QUADS) GL11.glTexCoord2f(0, 0) - GL11.glVertex2f(0, 0) + val matrix = stack.last.pose + val vec = new Vector4f(0, 0, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glTexCoord2f(0, 1) - GL11.glVertex2f(0, texture.height) + vec.set(0, texture.height, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glTexCoord2f(1, 1) - GL11.glVertex2f(texture.width, texture.height) + vec.set(texture.width, texture.height, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glTexCoord2f(1, 0) - GL11.glVertex2f(texture.width, 0) + vec.set(texture.width, 0, 0, 1) + vec.transform(matrix) + GL11.glVertex3f(vec.x, vec.y, vec.z) GL11.glEnd() } - private class ImageTexture(val location: ResourceLocation) extends AbstractTexture { + private class ImageTexture(val location: ResourceLocation) extends Texture { var width = 0 var height = 0 - override def loadTexture(manager: IResourceManager): Unit = { - deleteGlTexture() + override def load(manager: IResourceManager): Unit = { + releaseId() var is: InputStream = null try { val resource = manager.getResource(location) is = resource.getInputStream val bi = ImageIO.read(is) - TextureUtil.uploadTextureImageAllocate(getGlTextureId, bi, false, false) + val data = MemoryUtil.memAllocInt(bi.getWidth * bi.getHeight) + val tempArr = Array.ofDim[Int]((1024 * 1024) min data.capacity) + val dy = tempArr.length / bi.getWidth + for (y0 <- 0 until bi.getHeight by dy) { + val currH = dy min (bi.getHeight - y0 - 1) + bi.getRGB(0, y0, bi.getWidth, currH, tempArr, 0, bi.getWidth) + data.put(tempArr, 0, bi.getWidth * currH) + } + + bind() + data.flip() + TextureUtil.initTexture(data, bi.getWidth, bi.getHeight) width = bi.getWidth height = bi.getHeight } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/AdapterRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/AdapterRenderer.scala index 9b5417e132..b6a06d7501 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/AdapterRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/AdapterRenderer.scala @@ -1,90 +1,84 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.texture.TextureMap -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing -import org.lwjgl.opengl.GL11 - -object AdapterRenderer extends TileEntitySpecialRenderer[tileentity.Adapter] { - override def render(adapter: tileentity.Adapter, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - - if (adapter.openSides.contains(true)) { - RenderState.pushAttrib() - RenderState.disableEntityLighting() - RenderState.makeItBlend() +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.texture.AtlasTexture +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction + +object AdapterRenderer extends Function[TileEntityRendererDispatcher, AdapterRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new AdapterRenderer(dispatch) +} - GlStateManager.pushMatrix() +class AdapterRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[tileentity.Adapter](dispatch) { + override def render(adapter: tileentity.Adapter, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - GlStateManager.scale(1.0025, -1.0025, 1.0025) - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + RenderSystem.color4f(1, 1, 1, 1) - bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE) + if (adapter.openSides.contains(true)) { + stack.pushPose() - val t = Tessellator.getInstance - val r = t.getBuffer + stack.translate(0.5, 0.5, 0.5) + stack.scale(1.0025f, -1.0025f, 1.0025f) + stack.translate(-0.5f, -0.5f, -0.5f) - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) val sideActivity = Textures.getSprite(Textures.Block.AdapterOn) - if (adapter.isSideOpen(EnumFacing.DOWN)) { - r.pos(0, 1, 0).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 1, 0).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() - r.pos(1, 1, 1).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(0, 1, 1).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() + if (adapter.isSideOpen(Direction.DOWN)) { + r.vertex(stack.last.pose, 0, 1, 0).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(sideActivity.getU0, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).uv(sideActivity.getU1, sideActivity.getV1).endVertex() } - if (adapter.isSideOpen(EnumFacing.UP)) { - r.pos(0, 0, 0).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(0, 0, 1).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 1).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 0).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() + if (adapter.isSideOpen(Direction.UP)) { + r.vertex(stack.last.pose, 0, 0, 0).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(sideActivity.getU0, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(sideActivity.getU0, sideActivity.getV1).endVertex() } - if (adapter.isSideOpen(EnumFacing.NORTH)) { - r.pos(1, 1, 0).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(0, 1, 0).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(0, 0, 0).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 0).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (adapter.isSideOpen(Direction.NORTH)) { + r.vertex(stack.last.pose, 1, 1, 0).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 0).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - if (adapter.isSideOpen(EnumFacing.SOUTH)) { - r.pos(0, 1, 1).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(1, 1, 1).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(1, 0, 1).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(0, 0, 1).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (adapter.isSideOpen(Direction.SOUTH)) { + r.vertex(stack.last.pose, 0, 1, 1).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - if (adapter.isSideOpen(EnumFacing.WEST)) { - r.pos(0, 1, 0).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(0, 1, 1).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(0, 0, 1).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(0, 0, 0).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (adapter.isSideOpen(Direction.WEST)) { + r.vertex(stack.last.pose, 0, 1, 0).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - if (adapter.isSideOpen(EnumFacing.EAST)) { - r.pos(1, 1, 1).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(1, 1, 0).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(1, 0, 0).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 1).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (adapter.isSideOpen(Direction.EAST)) { + r.vertex(stack.last.pose, 1, 1, 1).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/AssemblerRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/AssemblerRenderer.scala index c8dd054827..129f5b025e 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/AssemblerRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/AssemblerRenderer.scala @@ -1,75 +1,65 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.Assembler import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import org.lwjgl.opengl.GL11 +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.math.vector.Vector3f -object AssemblerRenderer extends TileEntitySpecialRenderer[Assembler] { +object AssemblerRenderer extends Function[TileEntityRendererDispatcher, AssemblerRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new AssemblerRenderer(dispatch) +} - override def render(assembler: Assembler, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { +class AssemblerRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Assembler](dispatch) { + override def render(assembler: Assembler, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - RenderState.pushAttrib() + RenderSystem.color4f(1, 1, 1, 1) - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(1) + stack.pushPose() - GlStateManager.pushMatrix() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + stack.translate(0.5, 0.5, 0.5) - val t = Tessellator.getInstance - val r = t.getBuffer - - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) { val icon = Textures.getSprite(Textures.Block.AssemblerTopOn) - r.pos(-0.5, 0.55, 0.5).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0.5, 0.55, 0.5).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0.5, 0.55, -0.5).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(-0.5, 0.55, -0.5).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, -0.5f, 0.55f, 0.5f).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0.5f, 0.55f, 0.5f).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0.5f, 0.55f, -0.5f).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, -0.5f, 0.55f, -0.5f).uv(icon.getU0, icon.getV0).endVertex() } - t.draw() - // TODO Unroll loop to draw all at once? - val indent = 6 / 16f + 0.005 + val indent = 6 / 16f + 0.005f for (i <- 0 until 4) { - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - if (assembler.isAssembling) { val icon = Textures.getSprite(Textures.Block.AssemblerSideAssembling) - r.pos(indent, 0.5, -indent).tex(icon.getInterpolatedU((0.5 - indent) * 16), icon.getMaxV).endVertex() - r.pos(indent, 0.5, indent).tex(icon.getInterpolatedU((0.5 + indent) * 16), icon.getMaxV).endVertex() - r.pos(indent, -0.5, indent).tex(icon.getInterpolatedU((0.5 + indent) * 16), icon.getMinV).endVertex() - r.pos(indent, -0.5, -indent).tex(icon.getInterpolatedU((0.5 - indent) * 16), icon.getMinV).endVertex() + r.vertex(stack.last.pose, indent, 0.5f, -indent).uv(icon.getU((0.5f - indent) * 16), icon.getV1).endVertex() + r.vertex(stack.last.pose, indent, 0.5f, indent).uv(icon.getU((0.5f + indent) * 16), icon.getV1).endVertex() + r.vertex(stack.last.pose, indent, -0.5f, indent).uv(icon.getU((0.5f + indent) * 16), icon.getV0).endVertex() + r.vertex(stack.last.pose, indent, -0.5f, -indent).uv(icon.getU((0.5f - indent) * 16), icon.getV0).endVertex() } { val icon = Textures.getSprite(Textures.Block.AssemblerSideOn) - r.pos(0.5005, 0.5, -0.5).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0.5005, 0.5, 0.5).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0.5005, -0.5, 0.5).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0.5005, -0.5, -0.5).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 0.5005f, 0.5f, -0.5f).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0.5005f, 0.5f, 0.5f).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0.5005f, -0.5f, 0.5f).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0.5005f, -0.5f, -0.5f).uv(icon.getU0, icon.getV0).endVertex() } - t.draw() - - GlStateManager.rotate(90, 0, 1, 0) + stack.mulPose(Vector3f.YP.rotationDegrees(90)) } - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/CaseRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/CaseRenderer.scala index 24af1347ae..99895e1d3d 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/CaseRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/CaseRenderer.scala @@ -1,73 +1,62 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.Case import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.RenderHelper -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation -import org.lwjgl.opengl.GL11 - -object CaseRenderer extends TileEntitySpecialRenderer[Case] { - override def render(computer: Case, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +import net.minecraft.util.math.vector.Vector3f - RenderState.pushAttrib() +object CaseRenderer extends Function[TileEntityRendererDispatcher, CaseRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new CaseRenderer(dispatch) +} - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(1) +class CaseRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Case](dispatch) { + override def render(computer: Case, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - GlStateManager.pushMatrix() + stack.pushPose() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + stack.translate(0.5, 0.5, 0.5) computer.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => stack.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => stack.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => stack.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } - GlStateManager.translate(-0.5, 0.5, 0.505) - GlStateManager.scale(1, -1, 1) + stack.translate(-0.5, 0.5, 0.505) + stack.scale(1, -1, 1) if (computer.isRunning) { - renderFrontOverlay(Textures.Block.CaseFrontOn) - if (System.currentTimeMillis() - computer.lastFileSystemAccess < 400 && computer.world.rand.nextDouble() > 0.1) { - renderFrontOverlay(Textures.Block.CaseFrontActivity) + renderFrontOverlay(stack, Textures.Block.CaseFrontOn, buffer.getBuffer(RenderTypes.BLOCK_OVERLAY)) + if (System.currentTimeMillis() - computer.lastFileSystemAccess < 400 && computer.world.random.nextDouble() > 0.1) { + renderFrontOverlay(stack, Textures.Block.CaseFrontActivity, buffer.getBuffer(RenderTypes.BLOCK_OVERLAY)) } } else if (computer.hasErrored && RenderUtil.shouldShowErrorLight(computer.hashCode)) { - renderFrontOverlay(Textures.Block.CaseFrontError) + renderFrontOverlay(stack, Textures.Block.CaseFrontError, buffer.getBuffer(RenderTypes.BLOCK_OVERLAY)) } - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } - private def renderFrontOverlay(texture: ResourceLocation): Unit = { - val t = Tessellator.getInstance - val r = t.getBuffer - - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - + private def renderFrontOverlay(stack: MatrixStack, texture: ResourceLocation, r: IVertexBuilder): Unit = { val icon = Textures.getSprite(texture) - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - t.draw() + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/ChargerRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/ChargerRenderer.scala index acd81901a8..429b7a4de8 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/ChargerRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/ChargerRenderer.scala @@ -1,82 +1,75 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.Charger import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing -import org.lwjgl.opengl.GL11 - -object ChargerRenderer extends TileEntitySpecialRenderer[Charger] { - override def render(charger: Charger, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3f + +object ChargerRenderer extends Function[TileEntityRendererDispatcher, ChargerRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new ChargerRenderer(dispatch) +} - if (charger.chargeSpeed > 0) { - RenderState.pushAttrib() +class ChargerRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Charger](dispatch) { + override def render(charger: Charger, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(1) - GlStateManager.color(1, 1, 1, 1) + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.pushMatrix() + if (charger.chargeSpeed > 0) { + stack.pushPose() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + stack.translate(0.5, 0.5, 0.5) charger.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => stack.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => stack.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => stack.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } - GlStateManager.translate(-0.5f, 0.5f, 0.5f) - GlStateManager.scale(1, -1, 1) - - val t = Tessellator.getInstance - val r = t.getBuffer + stack.translate(-0.5f, 0.5f, 0.5f) + stack.scale(1, -1, 1) - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) { - val inverse = 1 - charger.chargeSpeed + val inverse = 1 - charger.chargeSpeed.toFloat val icon = Textures.getSprite(Textures.Block.ChargerFrontOn) - r.pos(0, 1, 0.005).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0.005).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, inverse, 0.005).tex(icon.getMaxU, icon.getInterpolatedV(inverse * 16)).endVertex() - r.pos(0, inverse, 0.005).tex(icon.getMinU, icon.getInterpolatedV(inverse * 16)).endVertex() + r.vertex(stack.last.pose, 0, 1, 0.005f).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0.005f).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, inverse, 0.005f).uv(icon.getU1, icon.getV(inverse * 16)).endVertex() + r.vertex(stack.last.pose, 0, inverse, 0.005f).uv(icon.getU0, icon.getV(inverse * 16)).endVertex() } if (charger.hasPower) { val icon = Textures.getSprite(Textures.Block.ChargerSideOn) - r.pos(-0.005, 1, -1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(-0.005, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(-0.005, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(-0.005, 0, -1).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, -0.005f, 1, -1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, -0.005f, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, -0.005f, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, -0.005f, 0, -1).uv(icon.getU0, icon.getV0).endVertex() - r.pos(1, 1, -1.005).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, -1.005).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, -1.005).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, -1.005).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 1, 1, -1.005f).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, -1.005f).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, -1.005f).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, -1.005f).uv(icon.getU0, icon.getV0).endVertex() - r.pos(1.005, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1.005, 1, -1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1.005, 0, -1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1.005, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 1.005f, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1.005f, 1, -1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1.005f, 0, -1).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1.005f, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/DisassemblerRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/DisassemblerRenderer.scala index b57b468cdb..b129606b6c 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/DisassemblerRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/DisassemblerRenderer.scala @@ -1,74 +1,68 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import org.lwjgl.opengl.GL11 - -object DisassemblerRenderer extends TileEntitySpecialRenderer[tileentity.Disassembler] { - override def render(disassembler: tileentity.Disassembler, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher - if (disassembler.isActive) { - RenderState.pushAttrib() +object DisassemblerRenderer extends Function[TileEntityRendererDispatcher, DisassemblerRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new DisassemblerRenderer(dispatch) +} - RenderState.disableEntityLighting() - RenderState.makeItBlend() - GlStateManager.color(1, 1, 1, 1) +class DisassemblerRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[tileentity.Disassembler](dispatch) { + override def render(disassembler: tileentity.Disassembler, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - GlStateManager.pushMatrix() + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - GlStateManager.scale(1.0025, -1.0025, 1.0025) - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + if (disassembler.isActive) { + stack.pushPose() + + stack.translate(0.5, 0.5, 0.5) + stack.scale(1.0025f, -1.0025f, 1.0025f) + stack.translate(-0.5f, -0.5f, -0.5f) - val t = Tessellator.getInstance - val r = t.getBuffer - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) { val icon = Textures.getSprite(Textures.Block.DisassemblerTopOn) - r.pos(0, 0, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 0, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } { val icon = Textures.getSprite(Textures.Block.DisassemblerSideOn) - r.pos(1, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(1, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 1, 1, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/DiskDriveRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/DiskDriveRenderer.scala index a559eb1366..6068fe056e 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/DiskDriveRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/DiskDriveRenderer.scala @@ -1,84 +1,68 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.DiskDrive import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.OpenGlHelper -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.block.model.ItemCameraTransforms -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.entity.item.EntityItem -import net.minecraft.util.EnumFacing -import org.lwjgl.opengl.GL11 +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.model.ItemCameraTransforms +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3f + +object DiskDriveRenderer extends Function[TileEntityRendererDispatcher, DiskDriveRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new DiskDriveRenderer(dispatch) +} -object DiskDriveRenderer extends TileEntitySpecialRenderer[DiskDrive] { - override def render(drive: DiskDrive, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { +class DiskDriveRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[DiskDrive](dispatch) { + override def render(drive: DiskDrive, dt: Float, matrix: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - RenderState.pushAttrib() - GlStateManager.color(1, 1, 1, 1) + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.pushMatrix() + matrix.pushPose() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + matrix.translate(0.5, 0.5, 0.5) drive.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => matrix.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => matrix.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => matrix.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } drive.items(0) match { case stack if !stack.isEmpty => - GlStateManager.pushMatrix() - GlStateManager.translate(0, 3.5f / 16, 6 / 16f) - GlStateManager.rotate(90, -1, 0, 0) - GlStateManager.scale(0.5f, 0.5f, 0.5f) + matrix.pushPose() + matrix.translate(0, 3.5f / 16, 6 / 16f) + matrix.mulPose(Vector3f.XN.rotationDegrees(90)) + matrix.scale(0.5f, 0.5f, 0.5f) - val brightness = drive.world.getCombinedLight(drive.getPos.offset(drive.facing), 0) - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, brightness % 65536, brightness / 65536) - - // This is very 'meh', but item frames do it like this, too! - val entity = new EntityItem(drive.world, 0, 0, 0, stack) - entity.hoverStart = 0 - Textures.Block.bind() - Minecraft.getMinecraft.getRenderItem.renderItem(entity.getItem, ItemCameraTransforms.TransformType.FIXED) - GlStateManager.popMatrix() + Minecraft.getInstance.getItemRenderer.renderStatic(stack, ItemCameraTransforms.TransformType.FIXED, light, overlay, matrix, buffer) + matrix.popPose() case _ => } - if (System.currentTimeMillis() - drive.lastAccess < 400 && drive.world.rand.nextDouble() > 0.1) { - GlStateManager.translate(-0.5, 0.5, 0.505) - GlStateManager.scale(1, -1, 1) - - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(1) + if (System.currentTimeMillis() - drive.lastAccess < 400 && drive.world.random.nextDouble() > 0.1) { + matrix.translate(-0.5, 0.5, 0.505) + matrix.scale(1, -1, 1) - val t = Tessellator.getInstance - val r = t.getBuffer - - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) val icon = Textures.getSprite(Textures.Block.DiskDriveFrontActivity) - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() + r.vertex(matrix.last.pose, 0, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(matrix.last.pose, 1, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(matrix.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(matrix.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } - GlStateManager.popMatrix() - RenderState.popAttrib() + matrix.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/GeolyzerRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/GeolyzerRenderer.scala index 16eeabdbf9..2d609c12ec 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/GeolyzerRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/GeolyzerRenderer.scala @@ -1,50 +1,42 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.Geolyzer import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import org.lwjgl.opengl.GL11 - -object GeolyzerRenderer extends TileEntitySpecialRenderer[Geolyzer] { - override def render(geolyzer: Geolyzer, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher - RenderState.pushAttrib() +object GeolyzerRenderer extends Function[TileEntityRendererDispatcher, GeolyzerRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new GeolyzerRenderer(dispatch) +} - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(1) - GlStateManager.color(1, 1, 1, 1) +class GeolyzerRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Geolyzer](dispatch) { + override def render(geolyzer: Geolyzer, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - GlStateManager.pushMatrix() + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - GlStateManager.scale(1.0025, -1.0025, 1.0025) - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + stack.pushPose() - val t = Tessellator.getInstance - val r = t.getBuffer + stack.translate(0.5, 0.5, 0.5) + stack.scale(1.0025f, -1.0025f, 1.0025f) + stack.translate(-0.5f, -0.5f, -0.5f) - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) val icon = Textures.getSprite(Textures.Block.GeolyzerTopOn) - r.pos(0, 0, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 0, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRenderer.scala index 39515d101b..9834f42212 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRenderer.scala @@ -1,30 +1,41 @@ package li.cil.oc.client.renderer.tileentity import java.nio.IntBuffer +import java.util.ArrayDeque +import java.util.function.Function import java.util.concurrent.Callable import java.util.concurrent.TimeUnit import com.google.common.cache.CacheBuilder import com.google.common.cache.RemovalListener import com.google.common.cache.RemovalNotification +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Settings import li.cil.oc.client.Textures import li.cil.oc.common.tileentity.Hologram import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.GlStateManager.CullFace -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3f +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.event.TickEvent.ClientTickEvent +import net.minecraftforge.eventbus.api.SubscribeEvent import org.lwjgl.BufferUtils import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL15 import scala.util.Random -object HologramRenderer extends TileEntitySpecialRenderer[Hologram] with Callable[Int] with RemovalListener[TileEntity, Int] { +object HologramRenderer extends Function[TileEntityRendererDispatcher, HologramRenderer] + with Callable[Int] with RemovalListener[TileEntity, Int] { + + override def apply(dispatch: TileEntityRendererDispatcher) = new HologramRenderer(dispatch) + private val random = new Random() /** We cache the VBOs for the projectors we render for performance. */ @@ -65,76 +76,86 @@ object HologramRenderer extends TileEntitySpecialRenderer[Hologram] with Callabl */ private var failed = false - override def render(hologram: Hologram, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - if (failed) { - HologramRendererFallback.render(hologram, x, y, z, f, damage, alpha) - return - } + private val renderQueue = new ArrayDeque[Hologram] - this.hologram = hologram - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") + // Defer actual rendering until now so transparent things render correctly. + @SubscribeEvent + def onRenderWorldLast(e: RenderWorldLastEvent): Unit = { + RenderState.checkError(getClass.getName + ".onRenderWorldLastEvent: entering (aka: wasntme)") + + val stack = e.getMatrixStack + val camPos = Minecraft.getInstance.gameRenderer.getMainCamera.getPosition + val buffer = Minecraft.getInstance.renderBuffers.bufferSource + + while (!renderQueue.isEmpty) { + val holo = renderQueue.removeFirst() + val pos = holo.getBlockPos + stack.pushPose() + stack.translate(pos.getX + 0.5 - camPos.x, pos.getY + 0.5 - camPos.y, pos.getZ + 0.5 - camPos.z) + doRender(holo, e.getPartialTicks, stack) + stack.popPose() + } - if (!hologram.hasPower) return + RenderState.checkError(getClass.getName + ".onRenderWorldLastEvent: leaving") + } - GL11.glPushClientAttrib(GL11.GL_ALL_CLIENT_ATTRIB_BITS) - RenderState.pushAttrib() + private def doRender(hologram: Hologram, f: Float, stack: MatrixStack) { + HologramRenderer.hologram = hologram + GL11.glPushClientAttrib(GL11.GL_CLIENT_ALL_ATTRIB_BITS) RenderState.makeItBlend() - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) + RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) - val playerDistSq = x * x + y * y + z * z - val maxDistSq = hologram.getMaxRenderDistanceSquared + val pos = hologram.getBlockPos + val relPos = Minecraft.getInstance.player.getEyePosition(f). + subtract(pos.getX + 0.5, pos.getY + 0.5, pos.getZ + 0.5) + val playerDistSq = relPos.dot(relPos) + val maxDistSq = hologram.getViewDistance * hologram.getViewDistance val fadeDistSq = hologram.getFadeStartDistanceSquared RenderState.setBlendAlpha(0.75f * (if (playerDistSq > fadeDistSq) math.max(0, 1 - ((playerDistSq - fadeDistSq) / (maxDistSq - fadeDistSq)).toFloat) else 1)) - GlStateManager.pushMatrix() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - hologram.yaw match { - case EnumFacing.WEST => GL11.glRotatef(-90, 0, 1, 0) - case EnumFacing.NORTH => GL11.glRotatef(180, 0, 1, 0) - case EnumFacing.EAST => GL11.glRotatef(90, 0, 1, 0) + case Direction.WEST => stack.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => stack.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => stack.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } hologram.pitch match { - case EnumFacing.DOWN => GL11.glRotatef(90, 1, 0, 0) - case EnumFacing.UP => GL11.glRotatef(-90, 1, 0, 0) + case Direction.DOWN => stack.mulPose(Vector3f.XP.rotationDegrees(90)) + case Direction.UP => stack.mulPose(Vector3f.XP.rotationDegrees(-90)) case _ => // No pitch. } - GlStateManager.rotate(hologram.rotationAngle, hologram.rotationX, hologram.rotationY, hologram.rotationZ) - GlStateManager.rotate(hologram.rotationSpeed * (hologram.getWorld.getTotalWorldTime % (360 * 20 - 1) + f) / 20f, hologram.rotationSpeedX, hologram.rotationSpeedY, hologram.rotationSpeedZ) + stack.mulPose(new Vector3f(hologram.rotationX, hologram.rotationY, hologram.rotationZ).rotationDegrees(hologram.rotationAngle)) + stack.mulPose(new Vector3f(hologram.rotationSpeedX, hologram.rotationSpeedY, hologram.rotationSpeedZ) + .rotationDegrees(hologram.rotationSpeed * (hologram.getLevel.getGameTime % (360 * 20 - 1) + f) / 20f)) - GlStateManager.scale(1.001, 1.001, 1.001) // Avoid z-fighting with other blocks. - GlStateManager.translate( + stack.scale(1.001f, 1.001f, 1.001f) // Avoid z-fighting with other blocks. + stack.translate( (hologram.translation.x * hologram.width / 16 - 1.5) * hologram.scale, hologram.translation.y * hologram.height / 16 * hologram.scale, (hologram.translation.z * hologram.width / 16 - 1.5) * hologram.scale) // Do a bit of flickering, because that's what holograms do! if (Settings.get.hologramFlickerFrequency > 0 && random.nextDouble() < Settings.get.hologramFlickerFrequency) { - GlStateManager.scale(1 + random.nextGaussian() * 0.01, 1 + random.nextGaussian() * 0.001, 1 + random.nextGaussian() * 0.01) - GlStateManager.translate(random.nextGaussian() * 0.01, random.nextGaussian() * 0.01, random.nextGaussian() * 0.01) + stack.scale(1 + random.nextGaussian().toFloat * 0.01f, 1 + random.nextGaussian().toFloat * 0.001f, 1 + random.nextGaussian().toFloat * 0.01f) + stack.translate(random.nextGaussian() * 0.01, random.nextGaussian() * 0.01, random.nextGaussian() * 0.01) } // After the below scaling, hologram is drawn inside a [0..48]x[0..32]x[0..48] box - GlStateManager.scale(hologram.scale / 16f, hologram.scale / 16f, hologram.scale / 16f) - - bindTexture(Textures.Model.HologramEffect) + stack.scale(hologram.scale.toFloat / 16f, hologram.scale.toFloat / 16f, hologram.scale.toFloat / 16f) - // Normalize normals (yes, glScale scales them too). - GL11.glEnable(GL11.GL_NORMALIZE) + Textures.bind(Textures.Model.HologramEffect) - val sx = (x + 0.5) * hologram.scale - val sy = -(y + 0.5) * hologram.scale - val sz = (z + 0.5) * hologram.scale + val sx = relPos.x * hologram.scale + val sy = relPos.y * hologram.scale + val sz = relPos.z * hologram.scale if (sx >= -1.5 && sx <= 1.5 && sz >= -1.5 && sz <= 1.5 && sy >= 0 && sy <= 2) { // Camera is inside the hologram. - GlStateManager.disableCull() + RenderSystem.disableCull() } else { // Camera is outside the hologram. - GlStateManager.enableCull() - GlStateManager.cullFace(CullFace.BACK) + RenderSystem.enableCull() } // We do two passes here to avoid weird transparency effects: in the first @@ -142,22 +163,21 @@ object HologramRenderer extends TileEntitySpecialRenderer[Hologram] with Callabl // When we don't do this the hologram will look different from different // angles (because some faces will shine through sometimes and sometimes // they won't), so a more... consistent look is desirable. + RenderSystem.pushMatrix() + RenderSystem.multMatrix(stack.last.pose) val glBuffer = cache.get(hologram, this) - GlStateManager.colorMask(false, false, false, false) - GlStateManager.depthMask(true) + GL11.glEnable(GL11.GL_DEPTH_TEST) + RenderSystem.colorMask(false, false, false, false) + RenderSystem.depthMask(true) draw(glBuffer) - GlStateManager.colorMask(true, true, true, true) - GlStateManager.depthFunc(GL11.GL_EQUAL) + RenderSystem.colorMask(true, true, true, true) + RenderSystem.depthFunc(GL11.GL_EQUAL) draw(glBuffer) - GlStateManager.depthFunc(GL11.GL_LEQUAL) - - GlStateManager.popMatrix() + RenderSystem.depthFunc(GL11.GL_LEQUAL) + RenderSystem.popMatrix() RenderState.disableBlend() - RenderState.popAttrib() GL11.glPopClientAttrib() - - RenderState.checkError(getClass.getName + ".render: leaving") } def draw(glBuffer: Int) { @@ -382,3 +402,14 @@ object HologramRenderer extends TileEntitySpecialRenderer[Hologram] with Callabl @SubscribeEvent def onTick(e: ClientTickEvent) = cache.cleanUp() } + +class HologramRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Hologram](dispatch) { + override def render(hologram: Hologram, f: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + if (HologramRenderer.failed) { + HologramRendererFallback.render(hologram, f, stack, buffer, light, overlay) + return + } + + if (hologram.hasPower) HologramRenderer.renderQueue.addLast(hologram) + } +} diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRendererFallback.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRendererFallback.scala index 850fbaeaf3..ae63453f3b 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRendererFallback.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRendererFallback.scala @@ -1,27 +1,34 @@ package li.cil.oc.client.renderer.tileentity +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.common.tileentity.Hologram import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.util.math.vector.Vector3f -object HologramRendererFallback extends TileEntitySpecialRenderer[Hologram] { +object HologramRendererFallback { var text = "Requires OpenGL 1.5" - override def render(hologram: Hologram, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { + def render(hologram: Hologram, f: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - val fontRenderer = Minecraft.getMinecraft.fontRenderer + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.pushMatrix() - GlStateManager.translate(x + 0.5, y + 0.75, z + 0.5) + val fontRenderer = Minecraft.getInstance.font - GlStateManager.scale(1 / 128f, -1 / 128f, 1 / 128f) - GlStateManager.disableCull() - fontRenderer.drawString(text, -fontRenderer.getStringWidth(text) / 2, 0, 0xFFFFFFFF) + stack.pushPose() + stack.translate(0.5, 0.75, 0.5) + stack.scale(1 / 128f, -1 / 128f, 1 / 128f) - GlStateManager.popMatrix() + fontRenderer.drawInBatch(text, -fontRenderer.width(text) / 2, 0, 0xFFFFFFFF, + false, stack.last.pose, buffer, false, 0, light) + stack.mulPose(Vector3f.YP.rotationDegrees(180)) + fontRenderer.drawInBatch(text, -fontRenderer.width(text) / 2, 0, 0xFFFFFFFF, + false, stack.last.pose, buffer, false, 0, light) + + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/MicrocontrollerRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/MicrocontrollerRenderer.scala index 26a0d4d82e..aec54a5b29 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/MicrocontrollerRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/MicrocontrollerRenderer.scala @@ -1,73 +1,66 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.Microcontroller import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.BufferBuilder -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation -import org.lwjgl.opengl.GL11 +import net.minecraft.util.math.vector.Vector3f -object MicrocontrollerRenderer extends TileEntitySpecialRenderer[Microcontroller] { - override def render(mcu: Microcontroller, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +object MicrocontrollerRenderer extends Function[TileEntityRendererDispatcher, MicrocontrollerRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new MicrocontrollerRenderer(dispatch) +} - RenderState.pushAttrib() +class MicrocontrollerRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Microcontroller](dispatch) { + override def render(mcu: Microcontroller, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(1) - GlStateManager.color(1, 1, 1, 1) + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.pushMatrix() + stack.pushPose() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + stack.translate(0.5, 0.5, 0.5) mcu.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => stack.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => stack.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => stack.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } - GlStateManager.translate(-0.5, 0.5, 0.505) - GlStateManager.scale(1, -1, 1) + stack.translate(-0.5, 0.5, 0.505) + stack.scale(1, -1, 1) - val t = Tessellator.getInstance - val r = t.getBuffer + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - - renderFrontOverlay(Textures.Block.MicrocontrollerFrontLight, r) + renderFrontOverlay(stack, Textures.Block.MicrocontrollerFrontLight, r) if (mcu.isRunning) { - renderFrontOverlay(Textures.Block.MicrocontrollerFrontOn, r) + renderFrontOverlay(stack, Textures.Block.MicrocontrollerFrontOn, r) } else if (mcu.hasErrored && RenderUtil.shouldShowErrorLight(mcu.hashCode)) { - renderFrontOverlay(Textures.Block.MicrocontrollerFrontError, r) + renderFrontOverlay(stack, Textures.Block.MicrocontrollerFrontError, r) } - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } - private def renderFrontOverlay(texture: ResourceLocation, r: BufferBuilder): Unit = { + private def renderFrontOverlay(stack: MatrixStack, texture: ResourceLocation, r: IVertexBuilder): Unit = { val icon = Textures.getSprite(texture) - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/NetSplitterRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/NetSplitterRenderer.scala index 847c653140..17627fa3b3 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/NetSplitterRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/NetSplitterRenderer.scala @@ -1,90 +1,86 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.texture.TextureMap -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing -import org.lwjgl.opengl.GL11 - -object NetSplitterRenderer extends TileEntitySpecialRenderer[tileentity.NetSplitter] { - override def render(splitter: tileentity.NetSplitter, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.texture.AtlasTexture +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction + +object NetSplitterRenderer extends Function[TileEntityRendererDispatcher, NetSplitterRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new NetSplitterRenderer(dispatch) +} - if (splitter.openSides.contains(!splitter.isInverted)) { - RenderState.pushAttrib() - RenderState.disableEntityLighting() - RenderState.makeItBlend() +class NetSplitterRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[tileentity.NetSplitter](dispatch) { + override def render(splitter: tileentity.NetSplitter, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - GlStateManager.pushMatrix() + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - GlStateManager.scale(1.0025, -1.0025, 1.0025) - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + if (splitter.openSides.contains(!splitter.isInverted)) { + stack.pushPose() - bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE) + stack.translate(0.5, 0.5, 0.5) + stack.scale(1.0025f, -1.0025f, 1.0025f) + stack.translate(-0.5f, -0.5f, -0.5f) - val t = Tessellator.getInstance - val r = t.getBuffer + Minecraft.getInstance().getModelManager().getAtlas(AtlasTexture.LOCATION_BLOCKS).bind() - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) val sideActivity = Textures.getSprite(Textures.Block.NetSplitterOn) - if (splitter.isSideOpen(EnumFacing.DOWN)) { - r.pos(0, 1, 0).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 1, 0).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() - r.pos(1, 1, 1).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(0, 1, 1).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() + if (splitter.isSideOpen(Direction.DOWN)) { + r.vertex(stack.last.pose, 0, 1, 0).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(sideActivity.getU0, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).uv(sideActivity.getU1, sideActivity.getV1).endVertex() } - if (splitter.isSideOpen(EnumFacing.UP)) { - r.pos(0, 0, 0).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(0, 0, 1).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 1).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 0).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() + if (splitter.isSideOpen(Direction.UP)) { + r.vertex(stack.last.pose, 0, 0, 0).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(sideActivity.getU0, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(sideActivity.getU0, sideActivity.getV1).endVertex() } - if (splitter.isSideOpen(EnumFacing.NORTH)) { - r.pos(1, 1, 0).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(0, 1, 0).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(0, 0, 0).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 0).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (splitter.isSideOpen(Direction.NORTH)) { + r.vertex(stack.last.pose, 1, 1, 0).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 0).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - if (splitter.isSideOpen(EnumFacing.SOUTH)) { - r.pos(0, 1, 1).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(1, 1, 1).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(1, 0, 1).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(0, 0, 1).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (splitter.isSideOpen(Direction.SOUTH)) { + r.vertex(stack.last.pose, 0, 1, 1).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - if (splitter.isSideOpen(EnumFacing.WEST)) { - r.pos(0, 1, 0).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(0, 1, 1).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(0, 0, 1).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(0, 0, 0).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (splitter.isSideOpen(Direction.WEST)) { + r.vertex(stack.last.pose, 0, 1, 0).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - if (splitter.isSideOpen(EnumFacing.EAST)) { - r.pos(1, 1, 1).tex(sideActivity.getMinU, sideActivity.getMaxV).endVertex() - r.pos(1, 1, 0).tex(sideActivity.getMaxU, sideActivity.getMaxV).endVertex() - r.pos(1, 0, 0).tex(sideActivity.getMaxU, sideActivity.getMinV).endVertex() - r.pos(1, 0, 1).tex(sideActivity.getMinU, sideActivity.getMinV).endVertex() + if (splitter.isSideOpen(Direction.EAST)) { + r.vertex(stack.last.pose, 1, 1, 1).uv(sideActivity.getU0, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(sideActivity.getU1, sideActivity.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(sideActivity.getU1, sideActivity.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(sideActivity.getU0, sideActivity.getV0).endVertex() } - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala index bd41d973b0..cf70b78788 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/PowerDistributorRenderer.scala @@ -1,75 +1,68 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import org.lwjgl.opengl.GL11 - -object PowerDistributorRenderer extends TileEntitySpecialRenderer[tileentity.PowerDistributor] { - override def render(distributor: tileentity.PowerDistributor, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher - if (distributor.globalBuffer > 0) { - RenderState.pushAttrib() +object PowerDistributorRenderer extends Function[TileEntityRendererDispatcher, PowerDistributorRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new PowerDistributorRenderer(dispatch) +} - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha((distributor.globalBuffer / distributor.globalBufferSize).toFloat) +class PowerDistributorRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[tileentity.PowerDistributor](dispatch) { + override def render(distributor: tileentity.PowerDistributor, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - GlStateManager.pushMatrix() + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - GlStateManager.scale(1.0025, -1.0025, 1.0025) - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + if (distributor.globalBuffer > 0) { + stack.pushPose() - val t = Tessellator.getInstance - val r = t.getBuffer + stack.translate(0.5, 0.5, 0.5) + stack.scale(1.0025f, -1.0025f, 1.0025f) + stack.translate(-0.5f, -0.5f, -0.5f) - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) { val icon = Textures.getSprite(Textures.Block.PowerDistributorTopOn) - r.pos(0, 0, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 0, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } { val icon = Textures.getSprite(Textures.Block.PowerDistributorSideOn) - r.pos(1, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(1, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 1, 1, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() } - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/PrinterRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/PrinterRenderer.scala index fd562d3063..761349b031 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/PrinterRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/PrinterRenderer.scala @@ -1,38 +1,42 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures import li.cil.oc.common.tileentity.Printer import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.OpenGlHelper +import net.minecraft.client.renderer.IRenderTypeBuffer import net.minecraft.client.renderer.RenderHelper -import net.minecraft.client.renderer.block.model.ItemCameraTransforms -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer +import net.minecraft.client.renderer.model.ItemCameraTransforms +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.math.vector.Vector3f +import org.lwjgl.opengl.GL13 + +object PrinterRenderer extends Function[TileEntityRendererDispatcher, PrinterRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new PrinterRenderer(dispatch) +} -object PrinterRenderer extends TileEntitySpecialRenderer[Printer] { - override def render(printer: Printer, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { +class PrinterRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Printer](dispatch) { + override def render(printer: Printer, dt: Float, matrix: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") if (printer.data.stateOff.nonEmpty) { val stack = printer.data.createItemStack() - RenderState.pushAttrib() - GlStateManager.pushMatrix() - - GlStateManager.translate(x + 0.5, y + 0.5 + 0.3, z + 0.5) - - GlStateManager.rotate((System.currentTimeMillis() % 20000) / 20000f * 360, 0, 1, 0) - GlStateManager.scale(0.75, 0.75, 0.75) + matrix.pushPose() + matrix.translate(0.5, 0.5 + 0.3, 0.5) - val brightness = printer.world.getCombinedLight(printer.getPos, 0) - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, brightness % 65536, brightness / 65536) + matrix.mulPose(Vector3f.YP.rotationDegrees((System.currentTimeMillis() % 20000) / 20000f * 360)) + matrix.scale(0.75f, 0.75f, 0.75f) Textures.Block.bind() - Minecraft.getMinecraft.getRenderItem.renderItem(stack, ItemCameraTransforms.TransformType.FIXED) + Minecraft.getInstance.getItemRenderer.renderStatic(stack, ItemCameraTransforms.TransformType.FIXED, light, overlay, matrix, buffer) - GlStateManager.popMatrix() - RenderState.popAttrib() + matrix.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/RackRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/RackRenderer.scala index e916ae1a2a..ebdf3c26ca 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/RackRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/RackRenderer.scala @@ -1,55 +1,58 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.api.event.RackMountableRenderEvent import li.cil.oc.common.tileentity.Rack import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.util.EnumFacing +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3f import net.minecraftforge.common.MinecraftForge import org.lwjgl.opengl.GL11 -object RackRenderer extends TileEntitySpecialRenderer[Rack] { +object RackRenderer extends Function[TileEntityRendererDispatcher, RackRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new RackRenderer(dispatch) +} + +class RackRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Rack](dispatch) { private final val vOffset = 2 / 16f private final val vSize = 3 / 16f - override def render(rack: Rack, x: Double, y: Double, z: Double, partialTicks: Float, destroyStage: Int, alpha: Float): Unit = { + override def render(rack: Rack, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - RenderState.pushAttrib() + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.pushMatrix() + stack.pushPose() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + stack.translate(0.5, 0.5, 0.5) rack.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => stack.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => stack.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => stack.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } - GlStateManager.translate(-0.5, 0.5, 0.505 - 0.5f / 16f) - GlStateManager.scale(1, -1, 1) + stack.translate(-0.5, 0.5, 0.505 - 0.5f / 16f) + stack.scale(1, -1, 1) // Note: we manually sync the rack inventory for this to work. - for (i <- 0 until rack.getSizeInventory) { - if (!rack.getStackInSlot(i).isEmpty) { - GlStateManager.pushMatrix() - RenderState.pushAttrib() - + for (i <- 0 until rack.getContainerSize) { + if (!rack.getItem(i).isEmpty) { val v0 = vOffset + i * vSize val v1 = vOffset + (i + 1) * vSize - val event = new RackMountableRenderEvent.TileEntity(rack, i, rack.lastData(i), v0, v1) + val event = new RackMountableRenderEvent.TileEntity(rack, i, rack.lastData(i), stack, buffer, light, overlay, v0, v1) MinecraftForge.EVENT_BUS.post(event) - - RenderState.popAttrib() - GlStateManager.popMatrix() } } - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/RaidRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/RaidRenderer.scala index 83b3bbb33e..b4bb92dd4c 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/RaidRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/RaidRenderer.scala @@ -1,72 +1,67 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.Raid import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.BufferBuilder +import net.minecraft.client.renderer.IRenderTypeBuffer import net.minecraft.client.renderer.texture.TextureAtlasSprite -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing -import org.lwjgl.opengl.GL11 +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3f -object RaidRenderer extends TileEntitySpecialRenderer[Raid] { - override def render(raid: Raid, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +object RaidRenderer extends Function[TileEntityRendererDispatcher, RaidRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new RaidRenderer(dispatch) +} - RenderState.pushAttrib() +class RaidRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Raid](dispatch) { + override def render(raid: Raid, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - RenderState.disableEntityLighting() - RenderState.makeItBlend() - GlStateManager.color(1, 1, 1, 1) + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.pushMatrix() + stack.pushPose() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + stack.translate(0.5, 0.5, 0.5) raid.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => stack.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => stack.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => stack.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } - GlStateManager.translate(-0.5, 0.5, 0.505) - GlStateManager.scale(1, -1, 1) + stack.translate(-0.5, 0.5, 0.505) + stack.scale(1, -1, 1) - val t = Tessellator.getInstance - val r = t.getBuffer - - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) { val icon = Textures.getSprite(Textures.Block.RaidFrontError) - for (slot <- 0 until raid.getSizeInventory) { + for (slot <- 0 until raid.getContainerSize) { if (!raid.presence(slot)) { - renderSlot(r, slot, icon) + renderSlot(stack, r, slot, icon) } } } { val icon = Textures.getSprite(Textures.Block.RaidFrontActivity) - for (slot <- 0 until raid.getSizeInventory) { - if (System.currentTimeMillis() - raid.lastAccess < 400 && raid.world.rand.nextDouble() > 0.1 && slot == raid.lastAccess % raid.getSizeInventory) { - renderSlot(r, slot, icon) + for (slot <- 0 until raid.getContainerSize) { + if (System.currentTimeMillis() - raid.lastAccess < 400 && raid.world.random.nextDouble() > 0.1 && slot == raid.lastAccess % raid.getContainerSize) { + renderSlot(stack, r, slot, icon) } } } - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } @@ -74,12 +69,12 @@ object RaidRenderer extends TileEntitySpecialRenderer[Raid] { private val u1 = 2 / 16f private val fs = 4 / 16f - private def renderSlot(r: BufferBuilder, slot: Int, icon: TextureAtlasSprite) { + private def renderSlot(stack: MatrixStack, r: IVertexBuilder, slot: Int, icon: TextureAtlasSprite) { val l = u1 + slot * fs val h = u1 + (slot + 1) * fs - r.pos(l, 1, 0).tex(icon.getInterpolatedU(l * 16), icon.getMaxV).endVertex() - r.pos(h, 1, 0).tex(icon.getInterpolatedU(h * 16), icon.getMaxV).endVertex() - r.pos(h, 0, 0).tex(icon.getInterpolatedU(h * 16), icon.getMinV).endVertex() - r.pos(l, 0, 0).tex(icon.getInterpolatedU(l * 16), icon.getMinV).endVertex() + r.vertex(stack.last.pose, l, 1, 0).uv(icon.getU(l * 16), icon.getV1).endVertex() + r.vertex(stack.last.pose, h, 1, 0).uv(icon.getU(h * 16), icon.getV1).endVertex() + r.vertex(stack.last.pose, h, 0, 0).uv(icon.getU(h * 16), icon.getV0).endVertex() + r.vertex(stack.last.pose, l, 0, 0).uv(icon.getU(l * 16), icon.getV0).endVertex() } } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/RelayRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/RelayRenderer.scala index ca447b2afb..efab260d61 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/RelayRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/RelayRenderer.scala @@ -1,66 +1,59 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import org.lwjgl.opengl.GL11 +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher + +object RelayRenderer extends Function[TileEntityRendererDispatcher, RelayRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new RelayRenderer(dispatch) +} -object RelayRenderer extends TileEntitySpecialRenderer[tileentity.Relay] { - override def render(switch: tileentity.Relay, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { +class RelayRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[tileentity.Relay](dispatch) { + override def render(switch: tileentity.Relay, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") + RenderSystem.color4f(1, 1, 1, 1) + val activity = math.max(0, 1 - (System.currentTimeMillis() - switch.lastMessage) / 1000.0) if (activity > 0) { - RenderState.pushAttrib() - - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(activity.toFloat) - - GlStateManager.pushMatrix() - - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - GlStateManager.scale(1.0025, -1.0025, 1.0025) - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + stack.pushPose() - val t = Tessellator.getInstance - val r = t.getBuffer + stack.translate(0.5, 0.5, 0.5) + stack.scale(1.0025f, -1.0025f, 1.0025f) + stack.translate(-0.5f, -0.5f, -0.5f) - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY) val icon = Textures.getSprite(Textures.Block.SwitchSideOn) - r.pos(1, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(1, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 1, 1, 1).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() + + stack.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala index 3af604a955..b52d6ce108 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/RobotRenderer.scala @@ -1,12 +1,16 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + import com.google.common.base.Strings +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api.driver.item.UpgradeRenderer import li.cil.oc.api.driver.item.UpgradeRenderer.MountPointName import li.cil.oc.api.event.RobotRenderEvent -import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.EventHandler import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState @@ -14,29 +18,35 @@ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ import net.minecraft.client.Minecraft import net.minecraft.client.renderer._ -import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType -import net.minecraft.client.renderer.entity.RenderLivingBase -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer +import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.client.renderer.vertex.VertexFormat -import net.minecraft.client.renderer.vertex.VertexFormatElement -import net.minecraft.init.Items -import net.minecraft.item.ItemBlock +import net.minecraft.item.Items +import net.minecraft.item.BlockItem import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.Vec3d +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.util.math.vector.Vector3f +import net.minecraft.util.math.vector.Matrix3f import net.minecraft.util.text.TextFormatting -import net.minecraftforge.client.MinecraftForgeClient +import net.minecraftforge.client.ForgeHooksClient import net.minecraftforge.common.MinecraftForge -import org.lwjgl.opengl.GL11 -import scala.collection.convert.WrapAsJava._ import scala.collection.mutable +import scala.jdk.CollectionConverters._ import scala.language.implicitConversions -object RobotRenderer extends TileEntitySpecialRenderer[tileentity.RobotProxy] { - private val displayList = GLAllocation.generateDisplayLists(2) +object RobotRenderer extends Function[TileEntityRendererDispatcher, RobotRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new RobotRenderer(dispatch) + + private val instance = new RobotRenderer(null) + def renderChassis(stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, offset: Double = 0, isRunningOverride: Boolean = false) = + instance.renderChassis(stack, buffer, light, null, offset, isRunningOverride) +} + +class RobotRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[tileentity.RobotProxy](dispatch) { private val mountPoints = new Array[RobotRenderEvent.MountPoint](7) private val slotNameMapping = Map( @@ -60,88 +70,71 @@ object RobotRenderer extends TileEntitySpecialRenderer[tileentity.RobotProxy] { private val gt = 0.5f + gap private val gb = 0.5f - gap - // https://github.com/MinecraftForge/MinecraftForge/issues/2321 - val POSITION_TEX_NORMALF = new VertexFormat() - val NORMAL_3F = new VertexFormatElement(0, VertexFormatElement.EnumType.FLOAT, VertexFormatElement.EnumUsage.NORMAL, 3) - POSITION_TEX_NORMALF.addElement(DefaultVertexFormats.POSITION_3F) - POSITION_TEX_NORMALF.addElement(DefaultVertexFormats.TEX_2F) - POSITION_TEX_NORMALF.addElement(NORMAL_3F) - - private implicit def extendWorldRenderer(self: BufferBuilder): ExtendedWorldRenderer = new ExtendedWorldRenderer(self) + private implicit def extendWorldRenderer(self: IVertexBuilder): ExtendedWorldRenderer = new ExtendedWorldRenderer(self) - private class ExtendedWorldRenderer(val buffer: BufferBuilder) { - def normal(normal: Vec3d): BufferBuilder = { + private class ExtendedWorldRenderer(val buffer: IVertexBuilder) { + def normal(matrix: Matrix3f, normal: Vector3d): IVertexBuilder = { val normalized = normal.normalize() - buffer.normal(normalized.x.toFloat, normalized.y.toFloat, normalized.z.toFloat) + buffer.normal(matrix, normalized.x.toFloat, normalized.y.toFloat, normalized.z.toFloat) } } - private def drawTop(): Unit = { - val t = Tessellator.getInstance - val r = t.getBuffer + private def drawTop(stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, red: Int, green: Int, blue: Int): Unit = { + val r = buffer.getBuffer(RenderTypes.ROBOT_CHASSIS) - r.begin(GL11.GL_TRIANGLE_FAN, POSITION_TEX_NORMALF) + r.vertex(stack.last.pose, 0.5f, 1, 0.5f).color(red, green, blue, 0xFF).uv(0.25f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, 1)).endVertex() + r.vertex(stack.last.pose, l, gt, h).color(red, green, blue, 0xFF).uv(0, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gt, h).color(red, green, blue, 0xFF).uv(0.5f, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, 1)).endVertex() - r.pos(0.5f, 1, 0.5f).tex(0.25f, 0.25f).normal(new Vec3d(0, 0.2, 1)).endVertex() - r.pos(l, gt, h).tex(0, 0.5f).normal(new Vec3d(0, 0.2, 1)).endVertex() - r.pos(h, gt, h).tex(0.5f, 0.5f).normal(new Vec3d(0, 0.2, 1)).endVertex() - r.pos(h, gt, l).tex(0.5f, 0).normal(new Vec3d(1, 0.2, 0)).endVertex() - r.pos(l, gt, l).tex(0, 0).normal(new Vec3d(0, 0.2, -1)).endVertex() - r.pos(l, gt, h).tex(0, 0.5f).normal(new Vec3d(-1, 0.2, 0)).endVertex() + r.vertex(stack.last.pose, 0.5f, 1, 0.5f).color(red, green, blue, 0xFF).uv(0.25f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gt, h).color(red, green, blue, 0xFF).uv(0.5f, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gt, l).color(red, green, blue, 0xFF).uv(0.5f, 0).uv2(light).normal(stack.last.normal, new Vector3d(1, 0.2, 0)).endVertex() - t.draw() + r.vertex(stack.last.pose, 0.5f, 1, 0.5f).color(red, green, blue, 0xFF).uv(0.25f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gt, l).color(red, green, blue, 0xFF).uv(0.5f, 0).uv2(light).normal(stack.last.normal, new Vector3d(1, 0.2, 0)).endVertex() + r.vertex(stack.last.pose, l, gt, l).color(red, green, blue, 0xFF).uv(0, 0).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, -1)).endVertex() - r.begin(GL11.GL_QUADS, POSITION_TEX_NORMALF) + r.vertex(stack.last.pose, 0.5f, 1, 0.5f).color(red, green, blue, 0xFF).uv(0.25f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, 1)).endVertex() + r.vertex(stack.last.pose, l, gt, l).color(red, green, blue, 0xFF).uv(0, 0).uv2(light).normal(stack.last.normal, new Vector3d(0, 0.2, -1)).endVertex() + r.vertex(stack.last.pose, l, gt, h).color(red, green, blue, 0xFF).uv(0, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(-1, 0.2, 0)).endVertex() - r.pos(l, gt, h).tex(0, 1).normal(0, -1, 0).endVertex() - r.pos(l, gt, l).tex(0, 0.5).normal(0, -1, 0).endVertex() - r.pos(h, gt, l).tex(0.5, 0.5).normal(0, -1, 0).endVertex() - r.pos(h, gt, h).tex(0.5, 1).normal(0, -1, 0).endVertex() + r.vertex(stack.last.pose, l, gt, h).color(red, green, blue, 0xFF).uv(0, 1).uv2(light).normal(stack.last.normal, 0, -1, 0).endVertex() + r.vertex(stack.last.pose, l, gt, l).color(red, green, blue, 0xFF).uv(0, 0.5f).uv2(light).normal(stack.last.normal, 0, -1, 0).endVertex() + r.vertex(stack.last.pose, h, gt, l).color(red, green, blue, 0xFF).uv(0.5f, 0.5f).uv2(light).normal(stack.last.normal, 0, -1, 0).endVertex() - t.draw() + r.vertex(stack.last.pose, l, gt, h).color(red, green, blue, 0xFF).uv(0, 1).uv2(light).normal(stack.last.normal, 0, -1, 0).endVertex() + r.vertex(stack.last.pose, h, gt, l).color(red, green, blue, 0xFF).uv(0.5f, 0.5f).uv2(light).normal(stack.last.normal, 0, -1, 0).endVertex() + r.vertex(stack.last.pose, h, gt, h).color(red, green, blue, 0xFF).uv(0.5f, 1).uv2(light).normal(stack.last.normal, 0, -1, 0).endVertex() } - private def drawBottom(): Unit = { - val t = Tessellator.getInstance - val r = t.getBuffer + private def drawBottom(stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, red: Int, green: Int, blue: Int): Unit = { + val r = buffer.getBuffer(RenderTypes.ROBOT_CHASSIS) - r.begin(GL11.GL_TRIANGLE_FAN, POSITION_TEX_NORMALF) + r.vertex(stack.last.pose, 0.5f, 0.03f, 0.5f).color(red, green, blue, 0xFF).uv(0.75f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, 1)).endVertex() + r.vertex(stack.last.pose, l, gb, l).color(red, green, blue, 0xFF).uv(0.5f, 0).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gb, l).color(red, green, blue, 0xFF).uv(1, 0).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, 1)).endVertex() - r.pos(0.5f, 0.03f, 0.5f).tex(0.75f, 0.25f).normal(new Vec3d(0, -0.2, 1)).endVertex() - r.pos(l, gb, l).tex(0.5f, 0).normal(new Vec3d(0, -0.2, 1)).endVertex() - r.pos(h, gb, l).tex(1, 0).normal(new Vec3d(0, -0.2, 1)).endVertex() - r.pos(h, gb, h).tex(1, 0.5f).normal(new Vec3d(1, -0.2, 0)).endVertex() - r.pos(l, gb, h).tex(0.5f, 0.5f).normal(new Vec3d(0, -0.2, -1)).endVertex() - r.pos(l, gb, l).tex(0.5f, 0).normal(new Vec3d(-1, -0.2, 0)).endVertex() + r.vertex(stack.last.pose, 0.5f, 0.03f, 0.5f).color(red, green, blue, 0xFF).uv(0.75f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gb, l).color(red, green, blue, 0xFF).uv(1, 0).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gb, h).color(red, green, blue, 0xFF).uv(1, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(1, -0.2, 0)).endVertex() - t.draw() + r.vertex(stack.last.pose, 0.5f, 0.03f, 0.5f).color(red, green, blue, 0xFF).uv(0.75f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, 1)).endVertex() + r.vertex(stack.last.pose, h, gb, h).color(red, green, blue, 0xFF).uv(1, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(1, -0.2, 0)).endVertex() + r.vertex(stack.last.pose, l, gb, h).color(red, green, blue, 0xFF).uv(0.5f, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, -1)).endVertex() - r.begin(GL11.GL_QUADS, POSITION_TEX_NORMALF) + r.vertex(stack.last.pose, 0.5f, 0.03f, 0.5f).color(red, green, blue, 0xFF).uv(0.75f, 0.25f).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, 1)).endVertex() + r.vertex(stack.last.pose, l, gb, h).color(red, green, blue, 0xFF).uv(0.5f, 0.5f).uv2(light).normal(stack.last.normal, new Vector3d(0, -0.2, -1)).endVertex() + r.vertex(stack.last.pose, l, gb, l).color(red, green, blue, 0xFF).uv(0.5f, 0).uv2(light).normal(stack.last.normal, new Vector3d(-1, -0.2, 0)).endVertex() - r.pos(l, gb, l).tex(0, 0.5).normal(0, 1, 0).endVertex() - r.pos(l, gb, h).tex(0, 1).normal(0, 1, 0).endVertex() - r.pos(h, gb, h).tex(0.5, 1).normal(0, 1, 0).endVertex() - r.pos(h, gb, l).tex(0.5, 0.5).normal(0, 1, 0).endVertex() + r.vertex(stack.last.pose, l, gb, l).color(red, green, blue, 0xFF).uv(0, 0.5f).uv2(light).normal(stack.last.normal, 0, 1, 0).endVertex() + r.vertex(stack.last.pose, l, gb, h).color(red, green, blue, 0xFF).uv(0, 1).uv2(light).normal(stack.last.normal, 0, 1, 0).endVertex() + r.vertex(stack.last.pose, h, gb, h).color(red, green, blue, 0xFF).uv(0.5f, 1).uv2(light).normal(stack.last.normal, 0, 1, 0).endVertex() - t.draw() + r.vertex(stack.last.pose, l, gb, l).color(red, green, blue, 0xFF).uv(0, 0.5f).uv2(light).normal(stack.last.normal, 0, 1, 0).endVertex() + r.vertex(stack.last.pose, h, gb, h).color(red, green, blue, 0xFF).uv(0.5f, 1).uv2(light).normal(stack.last.normal, 0, 1, 0).endVertex() + r.vertex(stack.last.pose, h, gb, l).color(red, green, blue, 0xFF).uv(0.5f, 0.5f).uv2(light).normal(stack.last.normal, 0, 1, 0).endVertex() } - def compileList() { - GL11.glNewList(displayList, GL11.GL_COMPILE) - - drawTop() - - GL11.glEndList() - - GL11.glNewList(displayList + 1, GL11.GL_COMPILE) - - drawBottom() - - GL11.glEndList() - } - - compileList() - def resetMountPoints(running: Boolean) { val offset = if (running) 0 else -0.06f @@ -209,7 +202,7 @@ object RobotRenderer extends TileEntitySpecialRenderer[tileentity.RobotProxy] { mountPoints(6).rotation.setW(0) } - def renderChassis(robot: tileentity.Robot = null, offset: Double = 0, isRunningOverride: Boolean = false) { + def renderChassis(stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, robot: tileentity.Robot = null, offset: Double = 0, isRunningOverride: Boolean = false) { val isRunning = if (robot == null) isRunningOverride else robot.isRunning val size = 0.3f @@ -229,277 +222,209 @@ object RobotRenderer extends TileEntitySpecialRenderer[tileentity.RobotProxy] { val event = new RobotRenderEvent(robot, mountPoints) MinecraftForge.EVENT_BUS.post(event) if (!event.isCanceled) { - bindTexture(Textures.Model.Robot) + val color = event.getColorMultiplier + val (cr, cg, cb) = ((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF) if (!isRunning) { - GlStateManager.translate(0, -2 * gap, 0) + stack.translate(0, -2 * gap, 0) } - //GlStateManager.callList(displayList + 1) - drawBottom() + drawBottom(stack, buffer, light, cr, cg, cb) if (!isRunning) { - GlStateManager.translate(0, -2 * gap, 0) + stack.translate(0, -2 * gap, 0) } - - if (MinecraftForgeClient.getRenderPass > 0) return - - //GlStateManager.callList(displayList) - drawTop() - GlStateManager.color(1, 1, 1) + drawTop(stack, buffer, light, cr, cg, cb) if (isRunning) { - RenderState.disableEntityLighting() - - { - // Additive blending for the light. - RenderState.makeItBlend() - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) - // Light color. - val lightColor = if (robot != null && robot.info != null) robot.info.lightColor else 0xF23030 - val r = (lightColor >>> 16) & 0xFF - val g = (lightColor >>> 8) & 0xFF - val b = (lightColor >>> 0) & 0xFF - GlStateManager.color(r / 255f, g / 255f, b / 255f) - } - - val t = Tessellator.getInstance - val r = t.getBuffer - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(l, gt, l).tex(u0, v0).endVertex() - r.pos(l, gb, l).tex(u0, v1).endVertex() - r.pos(l, gb, h).tex(u1, v1).endVertex() - r.pos(l, gt, h).tex(u1, v0).endVertex() - - r.pos(l, gt, h).tex(u0, v0).endVertex() - r.pos(l, gb, h).tex(u0, v1).endVertex() - r.pos(h, gb, h).tex(u1, v1).endVertex() - r.pos(h, gt, h).tex(u1, v0).endVertex() - - r.pos(h, gt, h).tex(u0, v0).endVertex() - r.pos(h, gb, h).tex(u0, v1).endVertex() - r.pos(h, gb, l).tex(u1, v1).endVertex() - r.pos(h, gt, l).tex(u1, v0).endVertex() - - r.pos(h, gt, l).tex(u0, v0).endVertex() - r.pos(h, gb, l).tex(u0, v1).endVertex() - r.pos(l, gb, l).tex(u1, v1).endVertex() - r.pos(l, gt, l).tex(u1, v0).endVertex() - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() + // Light color. + val lightColor = if (event.lightColor < 0) { + if (robot != null && robot.info != null) robot.info.lightColor else 0xF23030 + } else event.lightColor & 0xFFFFFF + val red = (lightColor >>> 16) & 0xFF + val green = (lightColor >>> 8) & 0xFF + val blue = (lightColor >>> 0) & 0xFF + + val r = buffer.getBuffer(RenderTypes.ROBOT_LIGHT) + r.vertex(stack.last.pose, l, gt, l).color(red, green, blue, 0xFF).uv(u0, v0).endVertex() + r.vertex(stack.last.pose, l, gb, l).color(red, green, blue, 0xFF).uv(u0, v1).endVertex() + r.vertex(stack.last.pose, l, gb, h).color(red, green, blue, 0xFF).uv(u1, v1).endVertex() + r.vertex(stack.last.pose, l, gt, h).color(red, green, blue, 0xFF).uv(u1, v0).endVertex() + + r.vertex(stack.last.pose, l, gt, h).color(red, green, blue, 0xFF).uv(u0, v0).endVertex() + r.vertex(stack.last.pose, l, gb, h).color(red, green, blue, 0xFF).uv(u0, v1).endVertex() + r.vertex(stack.last.pose, h, gb, h).color(red, green, blue, 0xFF).uv(u1, v1).endVertex() + r.vertex(stack.last.pose, h, gt, h).color(red, green, blue, 0xFF).uv(u1, v0).endVertex() + + r.vertex(stack.last.pose, h, gt, h).color(red, green, blue, 0xFF).uv(u0, v0).endVertex() + r.vertex(stack.last.pose, h, gb, h).color(red, green, blue, 0xFF).uv(u0, v1).endVertex() + r.vertex(stack.last.pose, h, gb, l).color(red, green, blue, 0xFF).uv(u1, v1).endVertex() + r.vertex(stack.last.pose, h, gt, l).color(red, green, blue, 0xFF).uv(u1, v0).endVertex() + + r.vertex(stack.last.pose, h, gt, l).color(red, green, blue, 0xFF).uv(u0, v0).endVertex() + r.vertex(stack.last.pose, h, gb, l).color(red, green, blue, 0xFF).uv(u0, v1).endVertex() + r.vertex(stack.last.pose, l, gb, l).color(red, green, blue, 0xFF).uv(u1, v1).endVertex() + r.vertex(stack.last.pose, l, gt, l).color(red, green, blue, 0xFF).uv(u1, v0).endVertex() } - GlStateManager.color(1, 1, 1, 1) } } - override def render(proxy: tileentity.RobotProxy, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { + override def render(proxy: tileentity.RobotProxy, f: Float, matrix: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") val robot = proxy.robot - val worldTime = robot.getWorld.getTotalWorldTime + f + val worldTime = proxy.getLevel.getGameTime + f - GlStateManager.pushMatrix() - RenderState.pushAttrib() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + matrix.pushPose() + + matrix.translate(0.5, 0.5, 0.5) // If the move started while we were rendering and we have a reference to // the *old* proxy the robot would be rendered at the wrong position, so we // correct for the offset. if (robot.proxy != proxy) { - GlStateManager.translate(robot.proxy.x - proxy.x, robot.proxy.y - proxy.y, robot.proxy.z - proxy.z) + matrix.translate(robot.proxy.x - proxy.x, robot.proxy.y - proxy.y, robot.proxy.z - proxy.z) } if (robot.isAnimatingMove) { val remaining = (robot.animationTicksLeft - f) / robot.animationTicksTotal.toDouble - val delta = robot.moveFrom.get.subtract(robot.getPos) - GlStateManager.translate(delta.getX * remaining, delta.getY * remaining, delta.getZ * remaining) + val delta = robot.moveFrom.get.subtract(robot.getBlockPos) + matrix.translate(delta.getX * remaining, delta.getY * remaining, delta.getZ * remaining) } val timeJitter = robot.hashCode ^ 0xFF val hover = if (robot.isRunning) (Math.sin(timeJitter + worldTime / 20.0) * 0.03).toFloat else -0.03f - GlStateManager.translate(0, hover, 0) - - GlStateManager.pushMatrix() + matrix.translate(0, hover, 0) - GlStateManager.depthMask(true) - RenderState.enableEntityLighting() - GlStateManager.disableBlend() + matrix.pushPose() if (robot.isAnimatingTurn) { val remaining = (robot.animationTicksLeft - f) / robot.animationTicksTotal.toFloat - GlStateManager.rotate(90 * remaining, 0, robot.turnAxis, 0) + val axis = if (robot.turnAxis < 0) Vector3f.YN else Vector3f.YP + matrix.mulPose(axis.rotationDegrees(90 * remaining)) } robot.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => matrix.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => matrix.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => matrix.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + matrix.translate(-0.5f, -0.5f, -0.5f) val offset = timeJitter + worldTime / 20.0 - renderChassis(robot, offset) + renderChassis(matrix, buffer, light, robot, offset) - if (MinecraftForgeClient.getRenderPass == 0 && !robot.renderingErrored && x * x + y * y + z * z < 24 * 24) { - val itemRenderer = Minecraft.getMinecraft.getItemRenderer - StackOption(robot.getStackInSlot(0)) match { + val pos = proxy.getBlockPos + val dist = Minecraft.getInstance.player.position.distanceToSqr(pos.getX + 0.5, pos.getY + 0.5, pos.getZ + 0.5) + if (!robot.renderingErrored && dist < 24 * 24) { + val itemRenderer = Minecraft.getInstance.getItemRenderer + StackOption(robot.getItem(0)) match { case SomeStack(stack) => - RenderState.pushAttrib() - GlStateManager.pushMatrix() + matrix.pushPose() try { // Copy-paste from player render code, with minor adjustments for // robot scale. - GlStateManager.disableCull() - GlStateManager.enableRescaleNormal() - - GlStateManager.scale(1, -1, -1) - GlStateManager.translate(0, -8 * 0.0625F - 0.0078125F, -0.5F) + matrix.scale(1, -1, -1) + matrix.translate(0, -8 * 0.0625F - 0.0078125F, -0.5F) if (robot.isAnimatingSwing) { val wantedTicksPerCycle = 10 val cycles = math.max(robot.animationTicksTotal / wantedTicksPerCycle, 1) val ticksPerCycle = robot.animationTicksTotal / cycles val remaining = (robot.animationTicksLeft - f) / ticksPerCycle.toDouble - GlStateManager.rotate((Math.sin((remaining - remaining.toInt) * Math.PI) * 45).toFloat, 1, 0, 0) + matrix.mulPose(Vector3f.XP.rotationDegrees((Math.sin((remaining - remaining.toInt) * Math.PI) * 45).toFloat)) } val item = stack.getItem - if (item.isInstanceOf[ItemBlock]) { - GlStateManager.rotate(-90.0F, 1.0F, 0.0F, 0.0F) - GlStateManager.rotate(180.0F, 0.0F, 1.0F, 0.0F) + if (item.isInstanceOf[BlockItem]) { + matrix.mulPose(Vector3f.XP.rotationDegrees(180.0F)) + matrix.mulPose(Vector3f.YP.rotationDegrees(90.0F)) val scale = 0.625F - GlStateManager.scale(scale, scale, scale) + matrix.scale(scale, scale, scale) } else if (item == Items.BOW) { - GlStateManager.translate(1.5f/16f, -0.125F, -0.125F) - GlStateManager.rotate(10.0F, 0.0F, 0.0F, 1.0F) - val scale = 0.625F - GlStateManager.scale(scale, -scale, scale) - } - else if (item.isFull3D) { - if (item.shouldRotateAroundWhenRendering) { - GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F) - GlStateManager.translate(0.0F, -0.0625F, 0.0F) - } - - GlStateManager.translate(0.0F, 0.1875F, 0.0F) - GlStateManager.translate(0.0625F, -0.125F, -2/16F) + matrix.translate(0, -3f/16f, -0.125F) + matrix.mulPose(Vector3f.ZP.rotationDegrees(170.0F)) val scale = 0.625F - GlStateManager.scale(scale, -scale, scale) - GlStateManager.rotate(0.0F, 1.0F, 0.0F, 0.0F) - GlStateManager.rotate(0.0F, 0.0F, 1.0F, 0.0F) + matrix.scale(scale, scale, scale) } else { - GlStateManager.translate(0, 2f/16f, 0) - val scale = 0.875F - GlStateManager.scale(scale, scale, scale) - GlStateManager.rotate(90.0F, 0.0F, 1.0F, 0.0F) - GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F) + matrix.translate(1f/16f, 1f/16f, -2f/16f) + val scale = 0.625F + matrix.scale(scale, scale, scale) + matrix.mulPose(Vector3f.ZP.rotationDegrees(180.0F)) } - itemRenderer.renderItem(Minecraft.getMinecraft.player, stack, TransformType.THIRD_PERSON_RIGHT_HAND) + itemRenderer.renderStatic(Minecraft.getInstance.player, stack, TransformType.THIRD_PERSON_RIGHT_HAND, false, matrix, buffer, proxy.getLevel, light, overlay) } catch { case e: Throwable => OpenComputers.log.warn("Failed rendering equipped item.", e) robot.renderingErrored = true } - GlStateManager.enableCull() - GlStateManager.disableRescaleNormal() - GlStateManager.popMatrix() - RenderState.popAttrib() + matrix.popPose() case _ => } - if (MinecraftForgeClient.getRenderPass == 0) { - lazy val availableSlots = slotNameMapping.keys.to[mutable.Set] - lazy val wildcardRenderers = mutable.Buffer.empty[(ItemStack, UpgradeRenderer)] - lazy val slotMapping = Array.fill(mountPoints.length)(null: (ItemStack, UpgradeRenderer)) + lazy val availableSlots = slotNameMapping.keys.to(mutable.Set).asJava + lazy val wildcardRenderers = mutable.Buffer.empty[(ItemStack, UpgradeRenderer)] + lazy val slotMapping = Array.fill(mountPoints.length)(null: (ItemStack, UpgradeRenderer)) - val renderers = (robot.componentSlots ++ robot.containerSlots).map(robot.getStackInSlot). - collect { case stack if !stack.isEmpty && stack.getItem.isInstanceOf[UpgradeRenderer] => (stack, stack.getItem.asInstanceOf[UpgradeRenderer]) } + val renderers = (robot.componentSlots ++ robot.containerSlots).map(robot.getItem). + collect { case stack if !stack.isEmpty && stack.getItem.isInstanceOf[UpgradeRenderer] => (stack, stack.getItem.asInstanceOf[UpgradeRenderer]) } - for ((stack, renderer) <- renderers) { - val preferredSlot = renderer.computePreferredMountPoint(stack, robot, availableSlots) - if (availableSlots.remove(preferredSlot)) { - slotMapping(slotNameMapping(preferredSlot)) = (stack, renderer) - } - else if (preferredSlot == MountPointName.Any) { - wildcardRenderers += ((stack, renderer)) - } + for ((stack, renderer) <- renderers) { + val preferredSlot = renderer.computePreferredMountPoint(stack, robot, availableSlots) + if (availableSlots.remove(preferredSlot)) { + slotMapping(slotNameMapping(preferredSlot)) = (stack, renderer) } - - var firstEmpty = slotMapping.indexOf(null) - for (entry <- wildcardRenderers if firstEmpty >= 0) { - slotMapping(firstEmpty) = entry - firstEmpty = slotMapping.indexOf(null) + else if (preferredSlot == MountPointName.Any) { + wildcardRenderers += ((stack, renderer)) } + } - for ((info, mountPoint) <- (slotMapping, mountPoints).zipped if info != null) try { - val (stack, renderer) = info - GlStateManager.pushMatrix() - GlStateManager.translate(0.5f, 0.5f, 0.5f) - renderer.render(stack, mountPoint, robot, f) - GlStateManager.popMatrix() - } - catch { - case e: Throwable => - OpenComputers.log.warn("Failed rendering equipped upgrade.", e) - robot.renderingErrored = true - } + var firstEmpty = slotMapping.indexOf(null) + for (entry <- wildcardRenderers if firstEmpty >= 0) { + slotMapping(firstEmpty) = entry + firstEmpty = slotMapping.indexOf(null) + } + + for ((info, mountPoint) <- (slotMapping, mountPoints).zipped if info != null) try { + val (stack, renderer) = info + matrix.pushPose() + matrix.translate(0.5f, 0.5f, 0.5f) + renderer.render(matrix, buffer, stack, mountPoint, robot, f) + matrix.popPose() + } + catch { + case e: Throwable => + OpenComputers.log.warn("Failed rendering equipped upgrade.", e) + robot.renderingErrored = true } } - GlStateManager.popMatrix() + matrix.popPose() val name = robot.name - if (Settings.get.robotLabels && MinecraftForgeClient.getRenderPass == 1 && !Strings.isNullOrEmpty(name) && x * x + y * y + z * z < RenderLivingBase.NAME_TAG_RANGE) { - GlStateManager.pushMatrix() - + if (Settings.get.robotLabels && !Strings.isNullOrEmpty(name) && ForgeHooksClient.isNameplateInRenderDistance(null, dist)) { // This is pretty much copy-pasta from the entity's label renderer. - val t = Tessellator.getInstance - val r = t.getBuffer - val f = getFontRenderer + val f = Minecraft.getInstance.font val scale = 1.6f / 60f - val width = f.getStringWidth(name) + val width = f.width(name) val halfWidth = width / 2 + val bgColor = (255f * Minecraft.getInstance.options.getBackgroundOpacity(0.25F)).asInstanceOf[Int] << 24 - GlStateManager.translate(0, 0.8, 0) - GL11.glNormal3f(0, 1, 0) - GlStateManager.color(1, 1, 1) - - GlStateManager.rotate(-rendererDispatcher.entityYaw, 0, 1, 0) - GlStateManager.rotate(rendererDispatcher.entityPitch, 1, 0, 0) - GlStateManager.scale(-scale, -scale, scale) - - RenderState.makeItBlend() - GlStateManager.depthMask(false) - GlStateManager.disableLighting() - GlStateManager.disableTexture2D() - - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR) - r.pos(-halfWidth - 1, -1, 0).color(0, 0, 0, 0.5f).endVertex() - r.pos(-halfWidth - 1, 8, 0).color(0, 0, 0, 0.5f).endVertex() - r.pos(halfWidth + 1, 8, 0).color(0, 0, 0, 0.5f).endVertex() - r.pos(halfWidth + 1, -1, 0).color(0, 0, 0, 0.5f).endVertex() - t.draw() - - GlStateManager.enableTexture2D() // For the font. - f.drawString((if (EventHandler.isItTime) TextFormatting.OBFUSCATED.toString else "") + name, -halfWidth, 0, 0xFFFFFFFF) - - GlStateManager.depthMask(true) - GlStateManager.enableLighting() - RenderState.disableBlend() + matrix.translate(0, 0.8, 0) + matrix.mulPose(Minecraft.getInstance.getEntityRenderDispatcher.cameraOrientation) + matrix.scale(-scale, -scale, scale) - GlStateManager.popMatrix() + f.drawInBatch((if (EventHandler.isItTime) TextFormatting.OBFUSCATED.toString else "") + name, + -halfWidth, 0, -1, false, matrix.last.pose, buffer, false, bgColor, light) } - GlStateManager.popMatrix() - RenderState.popAttrib() + matrix.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala index 0beb9af08b..0faec2772e 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala @@ -1,24 +1,31 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity.Screen import li.cil.oc.integration.util.Wrench import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.OpenGlHelper -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.util.EnumFacing -import org.lwjgl.opengl.GL11 -import org.lwjgl.opengl.GL14 -import org.lwjgl.opengl.GLContext - -object ScreenRenderer extends TileEntitySpecialRenderer[Screen] { +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher +import net.minecraft.util.Direction +import net.minecraft.util.Hand +import net.minecraft.util.math.vector.Vector3f + +object ScreenRenderer extends Function[TileEntityRendererDispatcher, ScreenRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new ScreenRenderer(dispatch) +} + +class ScreenRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[Screen](dispatch) { private val maxRenderDistanceSq = Settings.get.maxScreenTextRenderDistance * Settings.get.maxScreenTextRenderDistance private val fadeDistanceSq = Settings.get.screenTextFadeStartDistance * Settings.get.screenTextFadeStartDistance @@ -32,13 +39,11 @@ object ScreenRenderer extends TileEntitySpecialRenderer[Screen] { api.Items.get(Constants.BlockName.ScreenTier2), api.Items.get(Constants.BlockName.ScreenTier3)) - private val canUseBlendColor = GLContext.getCapabilities.OpenGL14 - // ----------------------------------------------------------------------- // // Rendering // ----------------------------------------------------------------------- // - override def render(screen: Screen, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { + override def render(screen: Screen, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") this.screen = screen @@ -51,111 +56,85 @@ object ScreenRenderer extends TileEntitySpecialRenderer[Screen] { return } - // y = block.bottom - player.feet - // eye is higher, so the y delta should be more negative - val eye_delta: Double = y - Minecraft.getMinecraft.player.getEyeHeight + val eye_pos = Minecraft.getInstance.player.getEyePosition(dt) + val eye_delta: Double = screen.getBlockPos.getY - eye_pos.y // Crude check whether screen text can be seen by the local player based // on the player's position -> angle relative to screen. val screenFacing = screen.facing.getOpposite - if (screenFacing.getFrontOffsetX * (x + 0.5) + screenFacing.getFrontOffsetY * (eye_delta + 0.5) + screenFacing.getFrontOffsetZ * (z + 0.5) < 0) { + val x = screen.getBlockPos.getX - eye_pos.x + val z = screen.getBlockPos.getZ - eye_pos.z + if (screenFacing.getStepX * (x + 0.5) + screenFacing.getStepY * (eye_delta + 0.5) + screenFacing.getStepZ * (z + 0.5) < 0) { return } - RenderState.checkError(getClass.getName + ".render: checks") - - RenderState.pushAttrib() - - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 0xFF, 0xFF) - RenderState.disableEntityLighting() - RenderState.makeItBlend() - GlStateManager.color(1, 1, 1, 1) + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.pushMatrix() + stack.pushPose() - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) + stack.translate(0.5, 0.5, 0.5) RenderState.checkError(getClass.getName + ".render: setup") - drawOverlay() + drawOverlay(stack, buffer.getBuffer(RenderTypes.BLOCK_OVERLAY)) RenderState.checkError(getClass.getName + ".render: overlay") - if (distance > fadeDistanceSq) { - val alpha = math.max(0, 1 - ((distance - fadeDistanceSq) * fadeRatio).toFloat) - if (canUseBlendColor) { - GL14.glBlendColor(0, 0, 0, alpha) - GlStateManager.blendFunc(GL11.GL_CONSTANT_ALPHA, GL11.GL_ONE) - } - } + val alpha = if (distance > fadeDistanceSq) math.max(0, 1 - ((distance - fadeDistanceSq) * fadeRatio).toFloat) else 1f RenderState.checkError(getClass.getName + ".render: fade") if (screen.buffer.isRenderingEnabled) { - draw() + draw(stack, alpha, buffer) } - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + stack.popPose() RenderState.checkError(getClass.getName + ".render: leaving") } - private def transform() { + private def transform(stack: MatrixStack) { screen.yaw match { - case EnumFacing.WEST => GlStateManager.rotate(-90, 0, 1, 0) - case EnumFacing.NORTH => GlStateManager.rotate(180, 0, 1, 0) - case EnumFacing.EAST => GlStateManager.rotate(90, 0, 1, 0) + case Direction.WEST => stack.mulPose(Vector3f.YP.rotationDegrees(-90)) + case Direction.NORTH => stack.mulPose(Vector3f.YP.rotationDegrees(180)) + case Direction.EAST => stack.mulPose(Vector3f.YP.rotationDegrees(90)) case _ => // No yaw. } screen.pitch match { - case EnumFacing.DOWN => GlStateManager.rotate(90, 1, 0, 0) - case EnumFacing.UP => GlStateManager.rotate(-90, 1, 0, 0) + case Direction.DOWN => stack.mulPose(Vector3f.XP.rotationDegrees(90)) + case Direction.UP => stack.mulPose(Vector3f.XP.rotationDegrees(-90)) case _ => // No pitch. } // Fit area to screen (bottom left = bottom left). - GlStateManager.translate(-0.5f, -0.5f, 0.5f) - GlStateManager.translate(0, screen.height, 0) + stack.translate(-0.5f, -0.5f, 0.5f) + stack.translate(0, screen.height, 0) // Flip text upside down. - GlStateManager.scale(1, -1, 1) + stack.scale(1, -1, 1) } - private def drawOverlay() = if (screen.facing == EnumFacing.UP || screen.facing == EnumFacing.DOWN) { + private def drawOverlay(matrix: MatrixStack, r: IVertexBuilder) = if (screen.facing == Direction.UP || screen.facing == Direction.DOWN) { // Show up vector overlay when holding same screen block. - val stack = Minecraft.getMinecraft.player.getHeldItemMainhand + val stack = Minecraft.getInstance.player.getItemInHand(Hand.MAIN_HAND) if (!stack.isEmpty) { - if (Wrench.holdsApplicableWrench(Minecraft.getMinecraft.player, screen.getPos) || screens.contains(api.Items.get(stack))) { - GlStateManager.pushMatrix() - transform() - GlStateManager.depthMask(false) - GlStateManager.translate(screen.width / 2f - 0.5f, screen.height / 2f - 0.5f, 0.05f) - - val t = Tessellator.getInstance - val r = t.getBuffer - - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + if (Wrench.holdsApplicableWrench(Minecraft.getInstance.player, screen.getBlockPos) || screens.contains(api.Items.get(stack))) { + matrix.pushPose() + transform(matrix) + matrix.translate(screen.width / 2f - 0.5f, screen.height / 2f - 0.5f, 0.05f) val icon = Textures.getSprite(Textures.Block.ScreenUpIndicator) - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - t.draw() + r.vertex(matrix.last.pose, 0, 1, 0).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(matrix.last.pose, 1, 1, 0).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(matrix.last.pose, 1, 0, 0).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(matrix.last.pose, 0, 0, 0).uv(icon.getU0, icon.getV0).endVertex() - GlStateManager.depthMask(true) - GlStateManager.popMatrix() + matrix.popPose() } } } - private def draw() { + private def draw(stack: MatrixStack, alpha: Float, buffer: IRenderTypeBuffer) { RenderState.checkError(getClass.getName + ".draw: entering (aka: wasntme)") val sx = screen.width @@ -163,10 +142,10 @@ object ScreenRenderer extends TileEntitySpecialRenderer[Screen] { val tw = sx * 16f val th = sy * 16f - transform() + transform(stack) // Offset from border. - GlStateManager.translate(sx * 2.25f / tw, sy * 2.25f / th, 0) + stack.translate(sx * 2.25f / tw, sy * 2.25f / th, 0) // Inner size (minus borders). val isx = sx - (4.5f / 16) @@ -179,37 +158,37 @@ object ScreenRenderer extends TileEntitySpecialRenderer[Screen] { val scaleY = isy / sizeY if (true) { if (scaleX > scaleY) { - GlStateManager.translate(sizeX * 0.5f * (scaleX - scaleY), 0, 0) - GlStateManager.scale(scaleY, scaleY, 1) + stack.translate(sizeX * 0.5f * (scaleX - scaleY), 0, 0) + stack.scale(scaleY, scaleY, 1) } else { - GlStateManager.translate(0, sizeY * 0.5f * (scaleY - scaleX), 0) - GlStateManager.scale(scaleX, scaleX, 1) + stack.translate(0, sizeY * 0.5f * (scaleY - scaleX), 0) + stack.scale(scaleX, scaleX, 1) } } else { // Stretch to fit. - GlStateManager.scale(scaleX, scaleY, 1) + stack.scale(scaleX, scaleY, 1) } // Slightly offset the text so it doesn't clip into the screen. - GlStateManager.translate(0, 0, 0.01) + stack.translate(0, 0, 0.01) RenderState.checkError(getClass.getName + ".draw: setup") // Render the actual text. - screen.buffer.renderText() + screen.buffer.renderText(stack) RenderState.checkError(getClass.getName + ".draw: text") } private def playerDistanceSq() = { - val player = Minecraft.getMinecraft.player + val player = Minecraft.getInstance.player val bounds = screen.getRenderBoundingBox - val px = player.posX - val py = player.posY - val pz = player.posZ + val px = player.getX + val py = player.getY + val pz = player.getZ val ex = bounds.maxX - bounds.minX val ey = bounds.maxY - bounds.minY diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/TransposerRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/TransposerRenderer.scala index 095d0d678c..ad749314cf 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/TransposerRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/TransposerRenderer.scala @@ -1,76 +1,69 @@ package li.cil.oc.client.renderer.tileentity +import java.util.function.Function + +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.tileentity import li.cil.oc.util.RenderState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.Tessellator -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer -import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import org.lwjgl.opengl.GL11 - -object TransposerRenderer extends TileEntitySpecialRenderer[tileentity.Transposer] { - override def render(transposer: tileentity.Transposer, x: Double, y: Double, z: Double, f: Float, damage: Int, alpha: Float) { - RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") +import net.minecraft.client.renderer.IRenderTypeBuffer +import net.minecraft.client.renderer.tileentity.TileEntityRenderer +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher - val activity = math.max(0, 1 - (System.currentTimeMillis() - transposer.lastOperation) / 1000.0) - if (activity > 0) { - RenderState.pushAttrib() +object TransposerRenderer extends Function[TileEntityRendererDispatcher, TransposerRenderer] { + override def apply(dispatch: TileEntityRendererDispatcher) = new TransposerRenderer(dispatch) +} - RenderState.disableEntityLighting() - RenderState.makeItBlend() - RenderState.setBlendAlpha(activity.toFloat) +class TransposerRenderer(dispatch: TileEntityRendererDispatcher) extends TileEntityRenderer[tileentity.Transposer](dispatch) { + override def render(transposer: tileentity.Transposer, dt: Float, stack: MatrixStack, buffer: IRenderTypeBuffer, light: Int, overlay: Int) { + RenderState.checkError(getClass.getName + ".render: entering (aka: wasntme)") - GlStateManager.pushMatrix() + RenderSystem.color4f(1, 1, 1, 1) - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5) - GlStateManager.scale(1.0025, -1.0025, 1.0025) - GlStateManager.translate(-0.5f, -0.5f, -0.5f) + val activity = math.max(0, 1 - (System.currentTimeMillis() - transposer.lastOperation) / 1000.0f) + if (activity > 0) { + stack.pushPose() - val t = Tessellator.getInstance - val r = t.getBuffer + stack.translate(0.5, 0.5, 0.5) + stack.scale(1.0025f, -1.0025f, 1.0025f) + stack.translate(-0.5f, -0.5f, -0.5f) - Textures.Block.bind() - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) + val r = buffer.getBuffer(RenderTypes.BLOCK_OVERLAY_COLOR) val icon = Textures.getSprite(Textures.Block.TransposerOn) - r.pos(0, 1, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 1, 0).tex(icon.getMinU, icon.getMinV).endVertex() - r.pos(1, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - - r.pos(0, 0, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - r.pos(1, 0, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - - r.pos(1, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(0, 1, 0).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(0, 1, 1).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(0, 0, 1).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(0, 0, 0).tex(icon.getMinU, icon.getMinV).endVertex() - - r.pos(1, 1, 1).tex(icon.getMinU, icon.getMaxV).endVertex() - r.pos(1, 1, 0).tex(icon.getMaxU, icon.getMaxV).endVertex() - r.pos(1, 0, 0).tex(icon.getMaxU, icon.getMinV).endVertex() - r.pos(1, 0, 1).tex(icon.getMinU, icon.getMinV).endVertex() - - t.draw() - - RenderState.disableBlend() - RenderState.enableEntityLighting() - - GlStateManager.popMatrix() - RenderState.popAttrib() + r.vertex(stack.last.pose, 0, 1, 0).color(1, 1, 1, activity).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).color(1, 1, 1, activity).uv(icon.getU0, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).color(1, 1, 1, activity).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).color(1, 1, 1, activity).uv(icon.getU1, icon.getV1).endVertex() + + r.vertex(stack.last.pose, 0, 0, 0).color(1, 1, 1, activity).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).color(1, 1, 1, activity).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).color(1, 1, 1, activity).uv(icon.getU0, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).color(1, 1, 1, activity).uv(icon.getU0, icon.getV1).endVertex() + + r.vertex(stack.last.pose, 1, 1, 0).color(1, 1, 1, activity).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 0).color(1, 1, 1, activity).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).color(1, 1, 1, activity).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).color(1, 1, 1, activity).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 1).color(1, 1, 1, activity).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 1).color(1, 1, 1, activity).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).color(1, 1, 1, activity).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).color(1, 1, 1, activity).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 0, 1, 0).color(1, 1, 1, activity).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 1, 1).color(1, 1, 1, activity).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 0, 0, 1).color(1, 1, 1, activity).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 0, 0, 0).color(1, 1, 1, activity).uv(icon.getU0, icon.getV0).endVertex() + + r.vertex(stack.last.pose, 1, 1, 1).color(1, 1, 1, activity).uv(icon.getU0, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 1, 0).color(1, 1, 1, activity).uv(icon.getU1, icon.getV1).endVertex() + r.vertex(stack.last.pose, 1, 0, 0).color(1, 1, 1, activity).uv(icon.getU1, icon.getV0).endVertex() + r.vertex(stack.last.pose, 1, 0, 1).color(1, 1, 1, activity).uv(icon.getU0, icon.getV0).endVertex() + + stack.popPose() } RenderState.checkError(getClass.getName + ".render: leaving") diff --git a/src/main/scala/li/cil/oc/common/Achievement.scala b/src/main/scala/li/cil/oc/common/Achievement.scala index a7fed0a4ee..ae08527c3e 100644 --- a/src/main/scala/li/cil/oc/common/Achievement.scala +++ b/src/main/scala/li/cil/oc/common/Achievement.scala @@ -1,6 +1,6 @@ package li.cil.oc.common -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack //placeholder @@ -9,11 +9,11 @@ object Achievement { def init() { } - def onAssemble(stack: ItemStack, player: EntityPlayer): Unit = { + def onAssemble(stack: ItemStack, player: PlayerEntity): Unit = { } - def onCraft(stack: ItemStack, player: EntityPlayer): Unit = { + def onCraft(stack: ItemStack, player: PlayerEntity): Unit = { } } @@ -25,7 +25,7 @@ import li.cil.oc.OpenComputers import li.cil.oc.api.detail.ItemInfo import li.cil.oc.common.init.Items import li.cil.oc.util.StackOption -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.stats.StatBase import net.minecraft.stats.{Achievement => MCAchievement} @@ -249,13 +249,13 @@ object Achievement { AchievementPage.registerAchievementPage(new AchievementPage(OpenComputers.Name, All: _*)) } - def onAssemble(stack: ItemStack, player: EntityPlayer): Unit = { + def onAssemble(stack: ItemStack, player: PlayerEntity): Unit = { AssemblingMap.get(Items.get(stack)).foreach(player.addStat(_, 1)) } - def onCraft(stack: ItemStack, player: EntityPlayer): Unit = { + def onCraft(stack: ItemStack, player: PlayerEntity): Unit = { CraftingMap.get(Items.get(stack)).foreach(player.addStat(_, 1)) - CustomCraftingMap.find(entry => ItemStack.areItemStacksEqual(stack, entry._1)).foreach(entry => player.addStat(entry._2, 1)) + CustomCraftingMap.find(entry => ItemStack.matches(stack, entry._1)).foreach(entry => player.addStat(entry._2, 1)) } private def newAchievement(name: String) = new AchievementBuilder(name) diff --git a/src/main/scala/li/cil/oc/common/ComponentTracker.scala b/src/main/scala/li/cil/oc/common/ComponentTracker.scala index 84e01e2860..3caabb9979 100644 --- a/src/main/scala/li/cil/oc/common/ComponentTracker.scala +++ b/src/main/scala/li/cil/oc/common/ComponentTracker.scala @@ -3,12 +3,14 @@ package li.cil.oc.common import com.google.common.cache.Cache import com.google.common.cache.CacheBuilder import li.cil.oc.api.network.ManagedEnvironment +import net.minecraft.util.RegistryKey import net.minecraft.world.World import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable /** @@ -17,10 +19,10 @@ import scala.collection.mutable * containers. For now this is only used for screens / text buffer components. */ abstract class ComponentTracker { - private val worlds = mutable.Map.empty[Int, Cache[String, ManagedEnvironment]] + private val worlds = mutable.Map.empty[RegistryKey[World], Cache[String, ManagedEnvironment]] private def components(world: World) = { - worlds.getOrElseUpdate(world.provider.getDimension, + worlds.getOrElseUpdate(world.dimension, com.google.common.cache.CacheBuilder.newBuilder(). weakValues(). asInstanceOf[CacheBuilder[String, ManagedEnvironment]]. @@ -46,7 +48,10 @@ abstract class ComponentTracker { } @SubscribeEvent - def onWorldUnload(e: WorldEvent.Unload): Unit = clear(e.getWorld) + def onWorldUnload(e: WorldEvent.Unload): Unit = e.getWorld match { + case world: World => clear(world) + case _ => + } protected def clear(world: World): Unit = this.synchronized { components(world).invalidateAll() diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index 6a4faddeb3..59ffc590e7 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -15,7 +15,6 @@ import li.cil.oc.api.network.Environment import li.cil.oc.api.network.SidedComponent import li.cil.oc.api.network.SidedEnvironment import li.cil.oc.client.renderer.PetRenderer -import li.cil.oc.common.asm.ClassTransformer import li.cil.oc.common.capabilities.CapabilityColored import li.cil.oc.common.capabilities.CapabilityEnvironment import li.cil.oc.common.capabilities.CapabilitySidedComponent @@ -25,7 +24,6 @@ import li.cil.oc.common.item.data.MicrocontrollerData import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.item.data.TabletData import li.cil.oc.common.item.traits -import li.cil.oc.common.recipe.Recipes import li.cil.oc.common.tileentity.Robot import li.cil.oc.common.tileentity.traits.power import li.cil.oc.integration.Mods @@ -38,29 +36,36 @@ import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.StackOption._ import li.cil.oc.util._ -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.init.SoundEvents +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.util.SoundEvents import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity import net.minecraft.util.SoundCategory +import net.minecraft.util.Util +import net.minecraft.world.chunk.Chunk +import net.minecraft.world.server.ChunkHolder +import net.minecraft.world.server.ChunkManager +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.client.event.ClientPlayerNetworkEvent import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.event.AttachCapabilitiesEvent +import net.minecraftforge.event.TickEvent +import net.minecraftforge.event.TickEvent.ClientTickEvent +import net.minecraftforge.event.TickEvent.ServerTickEvent import net.minecraftforge.event.entity.EntityJoinWorldEvent +import net.minecraftforge.event.entity.player.PlayerEvent._ import net.minecraftforge.event.world.BlockEvent import net.minecraftforge.event.world.ChunkEvent import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.FMLCommonHandler -import net.minecraftforge.fml.common.Optional -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.PlayerEvent._ -import net.minecraftforge.fml.common.gameevent.TickEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ServerTickEvent -import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent - -import scala.collection.convert.WrapAsScala._ +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fml.common.ObfuscationReflectionHelper +import net.minecraftforge.fml.server.ServerLifecycleHooks + +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future @@ -113,29 +118,16 @@ object EventHandler { } } - @Optional.Method(modid = Mods.IDs.IndustrialCraft2) - def scheduleIC2Add(tileEntity: power.IndustrialCraft2Experimental) { - if (SideTracker.isServer) pendingServer.synchronized { - tileEntity match { - case tile: ic2.api.energy.tile.IEnergyTile => - pendingServer += (() => if (!tileEntity.addedToIC2PowerGrid && !tileEntity.isInvalid) { - MinecraftForge.EVENT_BUS.post(new ic2.api.energy.event.EnergyTileLoadEvent(tile)) - tileEntity.addedToIC2PowerGrid = true - }) - case _ => - } - } - } - - @Optional.Method(modid = Mods.IDs.AppliedEnergistics2) - def scheduleAE2Add(tileEntity: power.AppliedEnergistics2): Unit = { - if (SideTracker.isServer) pendingServer.synchronized { - tileEntity match { - case tile: IGridBlock => - pendingServer += (() => if (!tileEntity.isInvalid) { - tileEntity.getGridNode(AEPartLocation.INTERNAL).updateState() - }) - case _ => + object AE2 { + def scheduleAE2Add(tileEntity: power.AppliedEnergistics2): Unit = { + if (SideTracker.isServer) pendingServer.synchronized { + tileEntity match { + case tile: IGridBlock => + pendingServer += (() => if (!tileEntity.isRemoved) { + tileEntity.getGridNode(AEPartLocation.INTERNAL).updateState() + }) + case _ => + } } } } @@ -154,12 +146,13 @@ object EventHandler { if (!event.getCapabilities.containsKey(traits.Chargeable.KEY)) { event.getObject match { case stack: ItemStack => stack.getItem match { - case chargeable: traits.Chargeable => event.addCapability(traits.Chargeable.KEY, new traits.Chargeable.Provider(stack, chargeable)) - case _: li.cil.oc.api.driver.item.Chargeable => - li.cil.oc.common.item.Delegator.subItem(stack) match { - case Some(subItem: traits.Chargeable) => event.addCapability(traits.Chargeable.KEY, new traits.Chargeable.Provider(stack, subItem)) - case _ => - } + case chargeable: traits.Chargeable => { + val provider = new traits.Chargeable.Provider(stack, chargeable) + event.addCapability(traits.Chargeable.KEY, provider) + event.addListener(new Runnable { + override def run = provider.invalidate + }) + } case _ => } case _ => @@ -170,22 +163,42 @@ object EventHandler { @SubscribeEvent def onAttachCapabilities(event: AttachCapabilitiesEvent[TileEntity]): Unit = { event.getObject match { - case tileEntity: TileEntity with Environment => - event.addCapability(CapabilityEnvironment.ProviderEnvironment, new CapabilityEnvironment.Provider(tileEntity)) + case tileEntity: TileEntity with Environment => { + val provider = new CapabilityEnvironment.Provider(tileEntity) + event.addCapability(CapabilityEnvironment.ProviderEnvironment, provider) + event.addListener(new Runnable { + override def run = provider.invalidate + }) + } case _ => } event.getObject match { - case tileEntity: TileEntity with Environment with SidedComponent => - event.addCapability(CapabilitySidedComponent.SidedComponent, new CapabilitySidedComponent.Provider(tileEntity)) - case tileEntity: TileEntity with SidedEnvironment => - event.addCapability(CapabilitySidedEnvironment.ProviderSidedEnvironment, new CapabilitySidedEnvironment.Provider(tileEntity)) + case tileEntity: TileEntity with Environment with SidedComponent => { + val provider = new CapabilitySidedComponent.Provider(tileEntity) + event.addCapability(CapabilitySidedComponent.SidedComponent, provider) + event.addListener(new Runnable { + override def run = provider.invalidate + }) + } + case tileEntity: TileEntity with SidedEnvironment => { + val provider = new CapabilitySidedEnvironment.Provider(tileEntity) + event.addCapability(CapabilitySidedEnvironment.ProviderSidedEnvironment, provider) + event.addListener(new Runnable { + override def run = provider.invalidate + }) + } case _ => } event.getObject match { - case tileEntity: TileEntity with Colored => - event.addCapability(CapabilityColored.ProviderColored, new CapabilityColored.Provider(tileEntity)) + case tileEntity: TileEntity with Colored => { + val provider = new CapabilityColored.Provider(tileEntity) + event.addCapability(CapabilityColored.ProviderColored, provider) + event.addListener(new Runnable { + override def run = provider.invalidate + }) + } case _ => } } @@ -212,7 +225,7 @@ object EventHandler { val invalid = mutable.ArrayBuffer.empty[Robot] runningRobots.foreach(robot => { - if (robot.isInvalid) invalid += robot + if (robot.isRemoved) invalid += robot else if (robot.world != null) robot.machine.update() }) runningRobots --= invalid @@ -244,20 +257,11 @@ object EventHandler { @SubscribeEvent def playerLoggedIn(e: PlayerLoggedInEvent) { - if (SideTracker.isServer) e.player match { + if (SideTracker.isServer) e.getPlayer match { case _: FakePlayer => // Nope - case player: EntityPlayerMP => + case player: ServerPlayerEntity => if (!LuaStateFactory.isAvailable && !LuaStateFactory.luajRequested) { - player.sendMessage(Localization.Chat.WarningLuaFallback) - } - if (Recipes.hadErrors) { - player.sendMessage(Localization.Chat.WarningRecipes) - } - if (ClassTransformer.hadErrors) { - player.sendMessage(Localization.Chat.WarningClassTransformer) - } - if (ClassTransformer.hadSimpleComponentErrors) { - player.sendMessage(Localization.Chat.WarningSimpleComponent) + player.sendMessage(Localization.Chat.WarningLuaFallback, Util.NIL_UUID) } // Gaaah, MC 1.8 y u do this to me? Sending the packets here directly can lead to them // arriving on the client before it has a world and player instance, which causes all @@ -267,11 +271,12 @@ object EventHandler { ServerPacketSender.sendLootDisks(player) }) // Do update check in local games and for OPs. - val server = FMLCommonHandler.instance.getMinecraftServerInstance - if (!server.isDedicatedServer || server.getPlayerList.canSendCommands(player.getGameProfile)) { + val server = ServerLifecycleHooks.getCurrentServer + if (server.getPlayerList.isOp(player.getGameProfile)) { Future { - UpdateCheck.info onSuccess { - case Some(release) => player.sendMessage(Localization.Chat.InfoNewVersion(release.tag_name)) + UpdateCheck.info foreach { + case Some(release) => player.sendMessage(Localization.Chat.InfoNewVersion(release.tag_name), Util.NIL_UUID) + case _ => } } } @@ -280,7 +285,8 @@ object EventHandler { } @SubscribeEvent - def clientLoggedIn(e: ClientConnectedToServerEvent) { + @OnlyIn(Dist.CLIENT) + def clientLoggedIn(e: ClientPlayerNetworkEvent.LoggedInEvent) { PetRenderer.isInitialized = false PetRenderer.hidden.clear() Loot.disksForClient.clear() @@ -292,14 +298,14 @@ object EventHandler { @SubscribeEvent def onBlockBreak(e: BlockEvent.BreakEvent): Unit = { - e.getWorld.getTileEntity(e.getPos) match { + e.getWorld.getBlockEntity(e.getPos) match { case c: tileentity.Case => - if (c.isCreative && (!e.getPlayer.capabilities.isCreativeMode || !c.canInteract(e.getPlayer.getName))) { + if (c.isCreative && (!e.getPlayer.isCreative || !c.canInteract(e.getPlayer.getName.getString))) { e.setCanceled(true) } case r: tileentity.RobotProxy => val robot = r.robot - if (robot.isCreative && (!e.getPlayer.capabilities.isCreativeMode || !robot.canInteract(e.getPlayer.getName))) { + if (robot.isCreative && (!e.getPlayer.isCreative || !robot.canInteract(e.getPlayer.getName.getString))) { e.setCanceled(true) } case _ => @@ -308,27 +314,27 @@ object EventHandler { @SubscribeEvent def onPlayerRespawn(e: PlayerRespawnEvent) { - keyboards.foreach(_.releasePressedKeys(e.player)) + keyboards.foreach(_.releasePressedKeys(e.getPlayer)) } @SubscribeEvent def onPlayerChangedDimension(e: PlayerChangedDimensionEvent) { - keyboards.foreach(_.releasePressedKeys(e.player)) + keyboards.foreach(_.releasePressedKeys(e.getPlayer)) } @SubscribeEvent def onPlayerLogout(e: PlayerLoggedOutEvent) { - keyboards.foreach(_.releasePressedKeys(e.player)) + keyboards.foreach(_.releasePressedKeys(e.getPlayer)) } @SubscribeEvent def onEntityJoinWorld(e: EntityJoinWorldEvent): Unit = { - if (Settings.get.giveManualToNewPlayers && !e.getWorld.isRemote) e.getEntity match { - case player: EntityPlayer if !player.isInstanceOf[FakePlayer] => + if (Settings.get.giveManualToNewPlayers && !e.getWorld.isClientSide) e.getEntity match { + case player: PlayerEntity if !player.isInstanceOf[FakePlayer] => val persistedData = PlayerUtils.persistedData(player) if (!persistedData.getBoolean(Settings.namespace + "receivedManual")) { - persistedData.setBoolean(Settings.namespace + "receivedManual", true) - player.inventory.addItemStackToInventory(api.Items.get(Constants.ItemName.Manual).createItemStack(1)) + persistedData.putBoolean(Settings.namespace + "receivedManual", true) + player.inventory.add(api.Items.get(Constants.ItemName.Manual).createItemStack(1)) } case _ => } @@ -347,8 +353,8 @@ object EventHandler { didRecraft = recraft(e, navigationUpgrade, stack => { // Restore the map currently used in the upgrade. - Option(api.Driver.driverFor(e.crafting)) match { - case Some(driver) => StackOption(new ItemStack(driver.dataTag(stack).getCompoundTag(Settings.namespace + "map"))) + Option(api.Driver.driverFor(e.getCrafting)) match { + case Some(driver) => StackOption(ItemStack.of(driver.dataTag(stack).getCompound(Settings.namespace + "map"))) case _ => EmptyStack } }) || didRecraft @@ -374,21 +380,21 @@ object EventHandler { }) || didRecraft // Presents? - e.player match { + e.getPlayer match { case _: FakePlayer => // No presents for you, automaton. Such discrimination. Much bad conscience. - case player: EntityPlayerMP if player.getEntityWorld != null && !player.getEntityWorld.isRemote => + case player: ServerPlayerEntity if player.level != null && !player.level.isClientSide => // Presents!? If we didn't recraft, it's an OC item, and the time is right... - if (Settings.get.presentChance > 0 && !didRecraft && api.Items.get(e.crafting) != null && - e.player.getRNG.nextFloat() < Settings.get.presentChance && timeForPresents) { + if (Settings.get.presentChance > 0 && !didRecraft && api.Items.get(e.getCrafting) != null && + e.getPlayer.getRandom.nextFloat() < Settings.get.presentChance && timeForPresents) { // Presents! val present = api.Items.get(Constants.ItemName.Present).createItemStack(1) - e.player.world.playSound(e.player, e.player.posX, e.player.posY, e.player.posZ, SoundEvents.BLOCK_NOTE_PLING, SoundCategory.MASTER, 0.2f, 1f) - InventoryUtils.addToPlayerInventory(present, e.player) + e.getPlayer.level.playSound(e.getPlayer, e.getPlayer.getX, e.getPlayer.getY, e.getPlayer.getZ, SoundEvents.NOTE_BLOCK_PLING, SoundCategory.MASTER, 0.2f, 1f) + InventoryUtils.addToPlayerInventory(present, e.getPlayer) } case _ => // Nope. } - Achievement.onCraft(e.crafting, e.player) + Achievement.onCraft(e.getCrafting, e.getPlayer) } @SubscribeEvent @@ -396,8 +402,8 @@ object EventHandler { val entity = e.getOriginalEntity Option(entity).flatMap(e => Option(e.getItem)) match { case Some(stack) => - Achievement.onAssemble(stack, e.player) - Achievement.onCraft(stack, e.player) + Achievement.onAssemble(stack, e.getPlayer) + Achievement.onCraft(stack, e.getPlayer) case _ => // Huh. } } @@ -423,12 +429,12 @@ object EventHandler { } private def recraft(e: ItemCraftedEvent, item: ItemInfo, callback: ItemStack => StackOption): Boolean = { - if (api.Items.get(e.crafting) == item) { - for (slot <- 0 until e.craftMatrix.getSizeInventory) { - val stack = e.craftMatrix.getStackInSlot(slot) + if (api.Items.get(e.getCrafting) == item) { + for (slot <- 0 until e.getInventory.getContainerSize) { + val stack = e.getInventory.getItem(slot) if (api.Items.get(stack) == item) { callback(stack).foreach(extra => - InventoryUtils.addToPlayerInventory(extra, e.player)) + InventoryUtils.addToPlayerInventory(extra, e.getPlayer)) } } true @@ -436,19 +442,36 @@ object EventHandler { else false } + private val getChunks = ObfuscationReflectionHelper.findMethod(classOf[ChunkManager], "func_223491_f") + + private def getChunks(world: ServerWorld): Iterable[ChunkHolder] = try { + getChunks.invoke(world.getChunkSource.chunkMap).asInstanceOf[java.lang.Iterable[ChunkHolder]] + } + catch { + case e: Throwable => + throw new Error("Could not access server chunk list", e) + } + // This is called from the ServerThread *and* the ClientShutdownThread, which // can potentially happen at the same time... for whatever reason. So let's // synchronize what we're doing here to avoid race conditions (e.g. when // disposing networks, where this actually triggered an assert). @SubscribeEvent def onWorldUnload(e: WorldEvent.Unload): Unit = this.synchronized { - if (!e.getWorld.isRemote) { - e.getWorld.loadedTileEntityList.collect { + if (!e.getWorld.isClientSide) { + val world = e.getWorld.asInstanceOf[ServerWorld] + world.blockEntityList.collect { case te: tileentity.traits.TileEntity => te.dispose() } - e.getWorld.loadedEntityList.collect { - case host: MachineHost => host.machine.stop() - } + + getChunks(world).foreach(holder => { + val chunk = holder.getTickingChunk + if (chunk != null) chunk.getEntitySections.foreach { + _.iterator.collect { + case host: MachineHost => host.machine.stop() + } + } + }) Callbacks.clear() } @@ -458,18 +481,21 @@ object EventHandler { } @SubscribeEvent - def onChunkUnload(e: ChunkEvent.Unload): Unit = { - if (!e.getWorld.isRemote) { - e.getChunk.getEntityLists.foreach(_.collect { - case host: MachineHost => host.machine match { - case machine: Machine => scheduleClose(machine) - case _ => // Dafuq? - } - case rack: Rack => - (0 until rack.getSizeInventory). - map(rack.getMountable). - collect { case server: Server if server.machine != null => server.machine.stop() } - }) + def onChunkUnloaded(e: ChunkEvent.Unload): Unit = { + if (!e.getWorld.isClientSide) e.getChunk match { + case chunk: Chunk => { + chunk.getEntitySections.foreach(_.collect { + case host: MachineHost => host.machine match { + case machine: Machine => scheduleClose(machine) + case _ => // Dafuq? + } + case rack: Rack => + (0 until rack.getContainerSize). + map(rack.getMountable). + collect { case server: Server if server.machine != null => server.machine.stop() } + }) + } + case _ => } } } diff --git a/src/main/scala/li/cil/oc/common/GuiHandler.scala b/src/main/scala/li/cil/oc/common/GuiHandler.scala deleted file mode 100644 index 59e6f8b758..0000000000 --- a/src/main/scala/li/cil/oc/common/GuiHandler.scala +++ /dev/null @@ -1,103 +0,0 @@ -package li.cil.oc.common - -import li.cil.oc.common.inventory.{DatabaseInventory, DiskDriveMountableInventory, ServerInventory} -import li.cil.oc.common.item.Delegator -import li.cil.oc.util.BlockPosition -import li.cil.oc.util.ExtendedWorld._ -import li.cil.oc.server.component.{DiskDriveMountable, Server} -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.ItemStack -import net.minecraft.world.World -import net.minecraftforge.fml.common.network.IGuiHandler - -abstract class GuiHandler extends IGuiHandler { - override def getServerGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef = { - GuiType.Categories.get(id) match { - case Some(GuiType.Category.Block) => - world.getTileEntity(BlockPosition(x, GuiType.extractY(y), z)) match { - case t: tileentity.Adapter if id == GuiType.Adapter.id => - new container.Adapter(player.inventory, t) - case t: tileentity.Assembler if id == GuiType.Assembler.id => - new container.Assembler(player.inventory, t) - case t: tileentity.Charger if id == GuiType.Charger.id => - new container.Charger(player.inventory, t) - case t: tileentity.Case if id == GuiType.Case.id => - new container.Case(player.inventory, t) - case t: tileentity.Disassembler if id == GuiType.Disassembler.id => - new container.Disassembler(player.inventory, t) - case t: tileentity.DiskDrive if id == GuiType.DiskDrive.id => - new container.DiskDrive(player.inventory, t) - case t: tileentity.Printer if id == GuiType.Printer.id => - new container.Printer(player.inventory, t) - case t: tileentity.Raid if id == GuiType.Raid.id => - new container.Raid(player.inventory, t) - case t: tileentity.Relay if id == GuiType.Relay.id => - new container.Relay(player.inventory, t) - case t: tileentity.RobotProxy if id == GuiType.Robot.id => - new container.Robot(player.inventory, t.robot) - case t: tileentity.Rack if id == GuiType.Rack.id => - new container.Rack(player.inventory, t) - case t: tileentity.Rack if id == GuiType.ServerInRack.id => - val slot = GuiType.extractSlot(y) - val server = t.getMountable(slot).asInstanceOf[Server] - new container.Server(player.inventory, server, Option(server)) - case t: tileentity.Rack if id == GuiType.DiskDriveMountableInRack.id => - val slot = GuiType.extractSlot(y) - val drive = t.getMountable(slot).asInstanceOf[DiskDriveMountable] - new container.DiskDrive(player.inventory, drive) - case _ => null - } - case Some(GuiType.Category.Entity) => - world.getEntityByID(x) match { - case drone: entity.Drone if id == GuiType.Drone.id => - new container.Drone(player.inventory, drone) - case _ => null - } - case Some(GuiType.Category.Item) => { - val itemStackInUse = getItemStackInUse(id, player) - Delegator.subItem(itemStackInUse) match { - case Some(database: item.UpgradeDatabase) if id == GuiType.Database.id => - new container.Database(player.inventory, new DatabaseInventory { - override def container = itemStackInUse - - override def isUsableByPlayer(player: EntityPlayer) = player == player - }) - case Some(server: item.Server) if id == GuiType.Server.id => - new container.Server(player.inventory, new ServerInventory { - override def container = itemStackInUse - - override def isUsableByPlayer(player: EntityPlayer) = player == player - }) - case Some(tablet: item.Tablet) if id == GuiType.TabletInner.id => - val stack = itemStackInUse - if (stack.hasTagCompound) - new container.Tablet(player.inventory, item.Tablet.get(stack, player)) - else - null - case Some(drive: item.DiskDriveMountable) if id == GuiType.DiskDriveMountable.id => - new container.DiskDrive(player.inventory, new DiskDriveMountableInventory { - override def container: ItemStack = itemStackInUse - - override def isUsableByPlayer(player: EntityPlayer) = player == player - }) - case _ => null - } - } - case _ => null - } - } - - def getItemStackInUse(id: Int, player: EntityPlayer): ItemStack = { - val mainItem: ItemStack = player.getHeldItemMainhand - Delegator.subItem(mainItem) match { - case Some(drive: item.traits.FileSystemLike) if id == GuiType.Drive.id => mainItem - case Some(database: item.UpgradeDatabase) if id == GuiType.Database.id => mainItem - case Some(server: item.Server) if id == GuiType.Server.id => mainItem - case Some(tablet: item.Tablet) if id == GuiType.Tablet.id => mainItem - case Some(tablet: item.Tablet) if id == GuiType.TabletInner.id => mainItem - case Some(terminal: item.Terminal) if id == GuiType.Terminal.id => mainItem - case Some(drive: item.DiskDriveMountable) if id == GuiType.DiskDriveMountable.id => mainItem - case _ => player.inventory.offHandInventory.get(0) - } - } -} diff --git a/src/main/scala/li/cil/oc/common/GuiType.scala b/src/main/scala/li/cil/oc/common/GuiType.scala deleted file mode 100644 index ee001fc5b6..0000000000 --- a/src/main/scala/li/cil/oc/common/GuiType.scala +++ /dev/null @@ -1,56 +0,0 @@ -package li.cil.oc.common - -import li.cil.oc.util.ScalaEnum - -import scala.collection.mutable - -object GuiType extends ScalaEnum { - val Categories = mutable.Map.empty[Int, Category.Value] - - sealed trait EnumVal extends Value { - def id = ordinal - def subType: GuiType.Category.Value - Categories += ordinal -> subType - } - - val Adapter = new EnumVal { def name = "Adapter"; def subType = GuiType.Category.Block } - val Assembler = new EnumVal { def name = "Assembler"; def subType = GuiType.Category.Block } - val Case = new EnumVal { def name = "Case"; def subType = GuiType.Category.Block } - val Charger = new EnumVal { def name = "Charger"; def subType = GuiType.Category.Block } - val Database = new EnumVal { def name = "Database"; def subType = GuiType.Category.Item } - val Disassembler = new EnumVal { def name = "Disassembler"; def subType = GuiType.Category.Block } - val DiskDrive = new EnumVal { def name = "DiskDrive"; def subType = GuiType.Category.Block } - val DiskDriveMountable = new EnumVal { def name = "DiskDriveMountable"; def subType = GuiType.Category.Item } - val DiskDriveMountableInRack = new EnumVal { def name = "DiskDriveMountableInRack"; def subType = GuiType.Category.Block } - val Drive = new EnumVal { def name = "Drive"; def subType = GuiType.Category.Item } - val Drone = new EnumVal { def name = "Drone"; def subType = GuiType.Category.Entity } - val Manual = new EnumVal { def name = "Manual"; def subType = GuiType.Category.None } - val Printer = new EnumVal { def name = "Printer"; def subType = GuiType.Category.Block } - val Rack = new EnumVal { def name = "Rack"; def subType = GuiType.Category.Block } - val Raid = new EnumVal { def name = "Raid"; def subType = GuiType.Category.Block } - val Relay = new EnumVal { def name = "Relay"; def subType = GuiType.Category.Block } - val Robot = new EnumVal { def name = "Robot"; def subType = GuiType.Category.Block } - val Screen = new EnumVal { def name = "Screen"; def subType = GuiType.Category.Block } - val Server = new EnumVal { def name = "Server"; def subType = GuiType.Category.Item } - val ServerInRack = new EnumVal { def name = "ServerInRack"; def subType = GuiType.Category.Block } - val Switch = new EnumVal { def name = "Switch"; def subType = GuiType.Category.Block } - val Tablet = new EnumVal { def name = "Tablet"; def subType = GuiType.Category.Item } - val TabletInner = new EnumVal { def name = "TabletInner"; def subType = GuiType.Category.Item } - val Terminal = new EnumVal { def name = "Terminal"; def subType = GuiType.Category.Item } - val Waypoint = new EnumVal { def name = "Waypoint"; def subType = GuiType.Category.Block } - - object Category extends ScalaEnum { - sealed trait EnumVal extends Value - - val None = new EnumVal { def name = "None" } - val Block = new EnumVal { def name = "Block" } - val Entity = new EnumVal { def name = "Entity" } - val Item = new EnumVal { def name = "Item" } - } - - def embedSlot(y: Int, slot: Int) = (y & 0x00FFFFFF) | (slot << 24) - - def extractY(value: Int) = value & 0x00FFFFFF - - def extractSlot(value: Int) = (value >>> 24) & 0xFF -} diff --git a/src/main/scala/li/cil/oc/common/IMC.scala b/src/main/scala/li/cil/oc/common/IMC.scala index 3401977ba1..7e86efac31 100644 --- a/src/main/scala/li/cil/oc/common/IMC.scala +++ b/src/main/scala/li/cil/oc/common/IMC.scala @@ -14,94 +14,93 @@ import li.cil.oc.integration.util.Wrench import li.cil.oc.server.driver.Registry import li.cil.oc.server.machine.ProgramLocations import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagString +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.StringNBT import net.minecraft.util.math.BlockPos import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.common.event.FMLInterModComms.IMCEvent +import net.minecraftforge.fml.InterModComms.IMCMessage -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object IMC { - def handleEvent(e: IMCEvent): Unit = { - for (message <- e.getMessages) { - if (message.key == api.IMC.REGISTER_ASSEMBLER_TEMPLATE && message.isNBTMessage) { - if (message.getNBTValue.hasKey("name", NBT.TAG_STRING)) - OpenComputers.log.debug(s"Registering new assembler template '${message.getNBTValue.getString("name")}' from mod ${message.getSender}.") + def handleMessage(message: IMCMessage): Unit = { + message.getMessageSupplier.get.asInstanceOf[AnyRef] match { + case template: CompoundNBT if message.getMethod == api.IMC.REGISTER_ASSEMBLER_TEMPLATE => { + if (template.contains("name", NBT.TAG_STRING)) + OpenComputers.log.debug(s"Registering new assembler template '${template.getString("name")}' from mod ${message.getSenderModId}.") else - OpenComputers.log.debug(s"Registering new, unnamed assembler template from mod ${message.getSender}.") - try AssemblerTemplates.add(message.getNBTValue) catch { + OpenComputers.log.debug(s"Registering new, unnamed assembler template from mod ${message.getSenderModId}.") + try AssemblerTemplates.add(template) catch { case t: Throwable => OpenComputers.log.warn("Failed registering assembler template.", t) } } - else if (message.key == api.IMC.REGISTER_DISASSEMBLER_TEMPLATE && message.isNBTMessage) { - if (message.getNBTValue.hasKey("name", NBT.TAG_STRING)) - OpenComputers.log.debug(s"Registering new disassembler template '${message.getNBTValue.getString("name")}' from mod ${message.getSender}.") + case template: CompoundNBT if message.getMethod == api.IMC.REGISTER_DISASSEMBLER_TEMPLATE => { + if (template.contains("name", NBT.TAG_STRING)) + OpenComputers.log.debug(s"Registering new disassembler template '${template.getString("name")}' from mod ${message.getSenderModId}.") else - OpenComputers.log.debug(s"Registering new, unnamed disassembler template from mod ${message.getSender}.") - try DisassemblerTemplates.add(message.getNBTValue) catch { + OpenComputers.log.debug(s"Registering new, unnamed disassembler template from mod ${message.getSenderModId}.") + try DisassemblerTemplates.add(template) catch { case t: Throwable => OpenComputers.log.warn("Failed registering disassembler template.", t) } } - else if (message.key == api.IMC.REGISTER_TOOL_DURABILITY_PROVIDER && message.isStringMessage) { - OpenComputers.log.debug(s"Registering new tool durability provider '${message.getStringValue}' from mod ${message.getSender}.") - try ToolDurabilityProviders.add(getStaticMethod(message.getStringValue, classOf[ItemStack])) catch { + case name: String if message.getMethod == api.IMC.REGISTER_TOOL_DURABILITY_PROVIDER => { + OpenComputers.log.debug(s"Registering new tool durability provider '${name}' from mod ${message.getSenderModId}.") + try ToolDurabilityProviders.add(getStaticMethod(name, classOf[ItemStack])) catch { case t: Throwable => OpenComputers.log.warn("Failed registering tool durability provider.", t) } } - else if (message.key == api.IMC.REGISTER_WRENCH_TOOL && message.isStringMessage) { - OpenComputers.log.debug(s"Registering new wrench usage '${message.getStringValue}' from mod ${message.getSender}.") - try Wrench.addUsage(getStaticMethod(message.getStringValue, classOf[EntityPlayer], classOf[BlockPos], classOf[Boolean])) catch { + case name: String if message.getMethod == api.IMC.REGISTER_WRENCH_TOOL => { + OpenComputers.log.debug(s"Registering new wrench usage '${name}' from mod ${message.getSenderModId}.") + try Wrench.addUsage(getStaticMethod(name, classOf[PlayerEntity], classOf[BlockPos], classOf[Boolean])) catch { case t: Throwable => OpenComputers.log.warn("Failed registering wrench usage.", t) } } - else if (message.key == api.IMC.REGISTER_WRENCH_TOOL_CHECK && message.isStringMessage) { - OpenComputers.log.debug(s"Registering new wrench tool check '${message.getStringValue}' from mod ${message.getSender}.") - try Wrench.addCheck(getStaticMethod(message.getStringValue, classOf[ItemStack])) catch { + case name: String if message.getMethod == api.IMC.REGISTER_WRENCH_TOOL_CHECK => { + OpenComputers.log.debug(s"Registering new wrench tool check '${name}' from mod ${message.getSenderModId}.") + try Wrench.addCheck(getStaticMethod(name, classOf[ItemStack])) catch { case t: Throwable => OpenComputers.log.warn("Failed registering wrench check.", t) } } - else if (message.key == api.IMC.REGISTER_ITEM_CHARGE && message.isNBTMessage) { - OpenComputers.log.debug(s"Registering new item charge implementation '${message.getNBTValue.getString("name")}' from mod ${message.getSender}.") + case implInfo: CompoundNBT if message.getMethod == api.IMC.REGISTER_ITEM_CHARGE => { + OpenComputers.log.debug(s"Registering new item charge implementation '${implInfo.getString("name")}' from mod ${message.getSenderModId}.") try ItemCharge.add( - getStaticMethod(message.getNBTValue.getString("canCharge"), classOf[ItemStack]), - getStaticMethod(message.getNBTValue.getString("charge"), classOf[ItemStack], classOf[Double], classOf[Boolean]) + getStaticMethod(implInfo.getString("canCharge"), classOf[ItemStack]), + getStaticMethod(implInfo.getString("charge"), classOf[ItemStack], classOf[Double], classOf[Boolean]) ) catch { case t: Throwable => OpenComputers.log.warn("Failed registering item charge implementation.", t) } } - else if (message.key == api.IMC.BLACKLIST_PERIPHERAL && message.isStringMessage) { - OpenComputers.log.debug(s"Blacklisting CC peripheral '${message.getStringValue}' as requested by mod ${message.getSender}.") - if (!Settings.get.peripheralBlacklist.contains(message.getStringValue)) { - Settings.get.peripheralBlacklist.add(message.getStringValue) + case name: String if message.getMethod == api.IMC.BLACKLIST_PERIPHERAL => { + OpenComputers.log.debug(s"Blacklisting CC peripheral '${name}' as requested by mod ${message.getSenderModId}.") + if (!Settings.get.peripheralBlacklist.contains(name)) { + Settings.get.peripheralBlacklist.add(name) } } - else if (message.key == api.IMC.BLACKLIST_HOST && message.isNBTMessage) { - OpenComputers.log.debug(s"Blacklisting component '${message.getNBTValue.getString("name")}' for host '${message.getNBTValue.getString("host")}' as requested by mod ${message.getSender}.") - try Registry.blacklistHost(new ItemStack(message.getNBTValue.getCompoundTag("item")), Class.forName(message.getNBTValue.getString("host"))) catch { + case compInfo: CompoundNBT if message.getMethod == api.IMC.BLACKLIST_HOST => { + OpenComputers.log.debug(s"Blacklisting component '${compInfo.getString("name")}' for host '${compInfo.getString("host")}' as requested by mod ${message.getSenderModId}.") + try Registry.blacklistHost(ItemStack.of(compInfo.getCompound("item")), Class.forName(compInfo.getString("host"))) catch { case t: Throwable => OpenComputers.log.warn("Failed blacklisting component.", t) } } - else if (message.key == api.IMC.REGISTER_ASSEMBLER_FILTER && message.isStringMessage) { - OpenComputers.log.debug(s"Registering new assembler template filter '${message.getStringValue}' from mod ${message.getSender}.") - try AssemblerTemplates.addFilter(message.getStringValue) catch { + case name: String if message.getMethod == api.IMC.REGISTER_ASSEMBLER_FILTER => { + OpenComputers.log.debug(s"Registering new assembler template filter '${name}' from mod ${message.getSenderModId}.") + try AssemblerTemplates.addFilter(name) catch { case t: Throwable => OpenComputers.log.warn("Failed registering assembler template filter.", t) } } - else if (message.key == api.IMC.REGISTER_INK_PROVIDER && message.isStringMessage) { - OpenComputers.log.debug(s"Registering new ink provider '${message.getStringValue}' from mod ${message.getSender}.") - try PrintData.addInkProvider(getStaticMethod(message.getStringValue, classOf[ItemStack])) catch { + case name: String if message.getMethod == api.IMC.REGISTER_INK_PROVIDER => { + OpenComputers.log.debug(s"Registering new ink provider '${name}' from mod ${message.getSenderModId}.") + try PrintData.addInkProvider(getStaticMethod(name, classOf[ItemStack])) catch { case t: Throwable => OpenComputers.log.warn("Failed registering ink provider.", t) } } - else if (message.key == api.IMC.REGISTER_PROGRAM_DISK_LABEL && message.isNBTMessage) { - OpenComputers.log.debug(s"Registering new program location mapping for program '${message.getNBTValue.getString("program")}' being on disk '${message.getNBTValue.getString("label")}' from mod ${message.getSender}.") - ProgramLocations.addMapping(message.getNBTValue.getString("program"), message.getNBTValue.getString("label"), message.getNBTValue.getTagList("architectures", NBT.TAG_STRING).map((tag: NBTTagString) => tag.getString()).toArray: _*) - } - else { - OpenComputers.log.warn(s"Got an unrecognized or invalid IMC message '${message.key}' from mod ${message.getSender}.") + case diskInfo: CompoundNBT if message.getMethod == api.IMC.REGISTER_PROGRAM_DISK_LABEL => { + OpenComputers.log.debug(s"Registering new program location mapping for program '${diskInfo.getString("program")}' being on disk '${diskInfo.getString("label")}' from mod ${message.getSenderModId}.") + ProgramLocations.addMapping(diskInfo.getString("program"), diskInfo.getString("label"), diskInfo.getList("architectures", NBT.TAG_STRING).map((tag: StringNBT) => tag.getAsString()).toArray: _*) } + case _ => OpenComputers.log.warn(s"Got an unrecognized or invalid IMC message '${message.getMethod}' from mod ${message.getSenderModId}.") } } diff --git a/src/main/scala/li/cil/oc/common/Loot.scala b/src/main/scala/li/cil/oc/common/Loot.scala index 511e34ac17..f97c9edd9c 100644 --- a/src/main/scala/li/cil/oc/common/Loot.scala +++ b/src/main/scala/li/cil/oc/common/Loot.scala @@ -11,19 +11,22 @@ import li.cil.oc.api import li.cil.oc.api.fs.FileSystem import li.cil.oc.common.init.Items import li.cil.oc.util.Color -import net.minecraft.item.EnumDyeColor +import net.minecraft.item.DyeColor import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.common.DimensionManager +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.ResourceLocation +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.World +import net.minecraft.world.server.ServerWorld +import net.minecraft.world.storage.FolderName import net.minecraftforge.common.util.Constants.NBT import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.Loader -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable -//class Loot extends WeightedRandomChestContent(api.Items.get(Constants.ItemName.Floppy).item(), api.Items.get(Constants.ItemName.Floppy).createItemStack(1).getItemDamage, 1, 1, Settings.get.lootProbability) { +//class Loot extends WeightedRandomChestContent(api.Items.get(Constants.ItemName.Floppy).item(), api.Items.get(Constants.ItemName.Floppy).createItemStack(1).getDamageValue, 1, 1, Settings.get.lootProbability) { // override def generateChestContent(random: Random, newInventory: IInventory) = // Loot.randomDisk(random) match { // case Some(disk) => @@ -39,7 +42,7 @@ object Loot { // ChestGenHooks.PYRAMID_JUNGLE_CHEST, // ChestGenHooks.STRONGHOLD_LIBRARY) - val factories = mutable.Map.empty[String, Callable[FileSystem]] + val factories = mutable.Map.empty[ResourceLocation, Callable[FileSystem]] val globalDisks = mutable.ArrayBuffer.empty[(ItemStack, Int)] @@ -55,33 +58,27 @@ object Loot { val disksForClient = mutable.ArrayBuffer.empty[ItemStack] - def isLootDisk(stack: ItemStack): Boolean = api.Items.get(stack) == api.Items.get(Constants.ItemName.Floppy) && stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "lootFactory", NBT.TAG_STRING) + def isLootDisk(stack: ItemStack): Boolean = api.Items.get(stack) == api.Items.get(Constants.ItemName.Floppy) && stack.hasTag && stack.getTag.contains(Settings.namespace + "lootFactory", NBT.TAG_STRING) def randomDisk(rng: Random) = if (disksForSampling.nonEmpty) Some(disksForSampling(rng.nextInt(disksForSampling.length))) else None - def registerLootDisk(name: String, color: EnumDyeColor, factory: Callable[FileSystem], doRecipeCycling: Boolean): ItemStack = { - val mod = Loader.instance.activeModContainer.getModId + def registerLootDisk(name: String, loc: ResourceLocation, color: DyeColor, factory: Callable[FileSystem], doRecipeCycling: Boolean): ItemStack = { + OpenComputers.log.debug(s"Registering loot disk '$name' from mod ${loc.getNamespace}.") - OpenComputers.log.debug(s"Registering loot disk '$name' from mod $mod.") + val data = new CompoundNBT() + data.putString(Settings.namespace + "fs.label", name) - val modSpecificName = mod + ":" + name - - val data = new NBTTagCompound() - data.setString(Settings.namespace + "fs.label", name) - - val nbt = new NBTTagCompound() - nbt.setTag(Settings.namespace + "data", data) + val stack = Items.get(Constants.ItemName.Floppy).createItemStack(1) + val nbt = stack.getOrCreateTag + nbt.put(Settings.namespace + "data", data) // Store this top level, so it won't get wiped on save. - nbt.setString(Settings.namespace + "lootFactory", modSpecificName) - nbt.setInteger(Settings.namespace + "color", color.getDyeDamage) - - val stack = Items.get(Constants.ItemName.Floppy).createItemStack(1) - stack.setTagCompound(nbt) + nbt.putString(Settings.namespace + "lootFactory", loc.toString) + nbt.putInt(Settings.namespace + "color", color.getId) - Loot.factories += modSpecificName -> factory + Loot.factories += loc -> factory if(doRecipeCycling) { Loot.disksForCyclingServer += stack @@ -103,13 +100,13 @@ object Loot { } @SubscribeEvent - def initForWorld(e: WorldEvent.Load): Unit = if (!e.getWorld.isRemote && e.getWorld.provider.getDimension == 0) { - worldDisks.clear() - disksForSampling.clear() - if (!e.getWorld.isRemote) { - val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + "loot/") + def initForWorld(e: WorldEvent.Load): Unit = e.getWorld match { + case world: ServerWorld if world.dimension == World.OVERWORLD => { + worldDisks.clear() + disksForSampling.clear() + val path = world.getServer.getWorldPath(new FolderName(Settings.savePath)).toFile if (path.exists && path.isDirectory) { - val listFile = new io.File(path, "loot.properties") + val listFile = new io.File(path, "loot/loot.properties") if (listFile.exists && listFile.isFile) { try { val listStream = new io.FileInputStream(listFile) @@ -123,15 +120,16 @@ object Loot { } } } - } - for (entry <- globalDisks if !worldDisks.contains(entry)) { - worldDisks += entry - } - for ((stack, count) <- worldDisks) { - for (i <- 0 until count) { - disksForSampling += stack + for (entry <- globalDisks if !worldDisks.contains(entry)) { + worldDisks += entry + } + for ((stack, count) <- worldDisks) { + for (i <- 0 until count) { + disksForSampling += stack + } } } + case _ => } private def parseLootDisks(list: java.util.Properties, acc: mutable.ArrayBuffer[(ItemStack, Int)], external: Boolean) { @@ -139,7 +137,7 @@ object Loot { val value = list.getProperty(key) try value.split(":") match { case Array(name, count, color) => - acc += ((createLootDisk(name, key, external, Color.byOreName.get(color)), count.toInt)) + acc += ((createLootDisk(name, key, external, Some(Color.byName(color))), count.toInt)) case Array(name, count) => acc += ((createLootDisk(name, key, external), count.toInt)) case _ => @@ -151,14 +149,14 @@ object Loot { } } - def createLootDisk(name: String, path: String, external: Boolean, color: Option[EnumDyeColor] = None) = { + def createLootDisk(name: String, path: String, external: Boolean, color: Option[DyeColor] = None) = { val callable = if (external) new Callable[FileSystem] { override def call(): FileSystem = api.FileSystem.asReadOnly(api.FileSystem.fromSaveDirectory("loot/" + path, 0, false)) } else new Callable[FileSystem] { - override def call(): FileSystem = api.FileSystem.fromClass(OpenComputers.getClass, Settings.resourceDomain, "loot/" + path) + override def call(): FileSystem = api.FileSystem.fromResource(new ResourceLocation(Settings.resourceDomain, "loot/" + path)) } - val stack = registerLootDisk(path, color.getOrElse(EnumDyeColor.SILVER), callable, doRecipeCycling = true) - stack.setStackDisplayName(name) + val stack = registerLootDisk(path, new ResourceLocation(Settings.resourceDomain, path), color.getOrElse(DyeColor.LIGHT_GRAY), callable, doRecipeCycling = true) + stack.setHoverName(new StringTextComponent(name)) if (!external) { Items.registerStack(stack, path) } diff --git a/src/main/scala/li/cil/oc/common/PacketBuilder.scala b/src/main/scala/li/cil/oc/common/PacketBuilder.scala index 27d0bb8012..ac524d9183 100644 --- a/src/main/scala/li/cil/oc/common/PacketBuilder.scala +++ b/src/main/scala/li/cil/oc/common/PacketBuilder.scala @@ -1,5 +1,7 @@ package li.cil.oc.common +import java.util.function.Supplier + import java.io.BufferedOutputStream import java.io.ByteArrayOutputStream import java.io.DataOutputStream @@ -11,33 +13,36 @@ import io.netty.buffer.Unpooled import li.cil.oc.OpenComputers import li.cil.oc.api.network.EnvironmentHost import net.minecraft.entity.Entity -import net.minecraft.entity.player.EntityPlayerMP +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.network.PacketBuffer +import net.minecraft.nbt.CompoundNBT import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.world.World -import net.minecraftforge.fml.common.FMLCommonHandler -import net.minecraftforge.fml.common.network.internal.FMLProxyPacket +import net.minecraftforge.fml.network.PacketDistributor +import net.minecraftforge.fml.server.ServerLifecycleHooks +import net.minecraftforge.registries._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ abstract class PacketBuilder(stream: OutputStream) extends DataOutputStream(stream) { + def writeRegistryEntry[T <: IForgeRegistryEntry[T]](registry: IForgeRegistry[T], value: T): Unit = + writeInt(registry.asInstanceOf[ForgeRegistry[T]].getID(value)) + def writeTileEntity(t: TileEntity) { - writeInt(t.getWorld.provider.getDimension) - writeInt(t.getPos.getX) - writeInt(t.getPos.getY) - writeInt(t.getPos.getZ) + writeUTF(t.getLevel.dimension.location.toString) + writeInt(t.getBlockPos.getX) + writeInt(t.getBlockPos.getY) + writeInt(t.getBlockPos.getZ) } def writeEntity(e: Entity) { - writeInt(e.world.provider.getDimension) - writeInt(e.getEntityId) + writeUTF(e.level.dimension.location.toString) + writeInt(e.getId) } - def writeDirection(d: Option[EnumFacing]) = d match { + def writeDirection(d: Option[Direction]) = d match { case Some(side) => writeByte(side.ordinal.toByte) case _ => writeByte(-1: Byte) } @@ -46,11 +51,11 @@ abstract class PacketBuilder(stream: OutputStream) extends DataOutputStream(stre val haveStack = !stack.isEmpty && stack.getCount > 0 writeBoolean(haveStack) if (haveStack) { - writeNBT(stack.writeToNBT(new NBTTagCompound())) + writeNBT(stack.save(new CompoundNBT())) } } - def writeNBT(nbt: NBTTagCompound) = { + def writeNBT(nbt: CompoundNBT) = { val haveNbt = nbt != null writeBoolean(haveNbt) if (haveNbt) { @@ -60,32 +65,33 @@ abstract class PacketBuilder(stream: OutputStream) extends DataOutputStream(stre def writePacketType(pt: PacketType.Value) = writeByte(pt.id) - def sendToAllPlayers() = OpenComputers.channel.sendToAll(packet) + def sendToAllPlayers() = OpenComputers.channel.send(PacketDistributor.ALL.noArg(), packet) - def sendToPlayersNearEntity(e: Entity, range: Option[Double] = None): Unit = sendToNearbyPlayers(e.getEntityWorld, e.posX, e.posY, e.posZ, range) + def sendToPlayersNearEntity(e: Entity, range: Option[Double] = None): Unit = sendToNearbyPlayers(e.level, e.getX, e.getY, e.getZ, range) - def sendToPlayersNearTileEntity(t: TileEntity, range: Option[Double] = None): Unit = sendToNearbyPlayers(t.getWorld, t.getPos.getX + 0.5, t.getPos.getY + 0.5, t.getPos.getZ + 0.5, range) + def sendToPlayersNearTileEntity(t: TileEntity, range: Option[Double] = None): Unit = sendToNearbyPlayers(t.getLevel, t.getBlockPos.getX + 0.5, t.getBlockPos.getY + 0.5, t.getBlockPos.getZ + 0.5, range) def sendToPlayersNearHost(host: EnvironmentHost, range: Option[Double] = None): Unit = sendToNearbyPlayers(host.world, host.xPosition, host.yPosition, host.zPosition, range) def sendToNearbyPlayers(world: World, x: Double, y: Double, z: Double, range: Option[Double]) { - val dimension = world.provider.getDimension - val server = FMLCommonHandler.instance.getMinecraftServerInstance + val server = ServerLifecycleHooks.getCurrentServer val manager = server.getPlayerList - for (player <- manager.getPlayers if player.dimension == dimension) { - val playerRenderDistance = 16 // ObfuscationReflectionHelper.getPrivateValue(classOf[EntityPlayerMP], player, "renderDistance").asInstanceOf[Integer] + for (player <- manager.getPlayers if player.level == world) { + val playerRenderDistance = 16 val playerSpecificRange = range.getOrElse((manager.getViewDistance min playerRenderDistance) * 16.0) - if (player.getDistanceSq(x, y, z) < playerSpecificRange * playerSpecificRange) { + if (player.distanceToSqr(x, y, z) < playerSpecificRange * playerSpecificRange) { sendToPlayer(player) } } } - def sendToPlayer(player: EntityPlayerMP) = OpenComputers.channel.sendTo(packet, player) + def sendToPlayer(player: ServerPlayerEntity) = OpenComputers.channel.send(PacketDistributor.PLAYER.`with`(new Supplier[ServerPlayerEntity] { + override def get = player + }), packet) def sendToServer() = OpenComputers.channel.sendToServer(packet) - protected def packet: FMLProxyPacket + protected def packet: Array[Byte] } // Necessary to keep track of the GZIP stream. @@ -96,7 +102,7 @@ class SimplePacketBuilder(val packetType: PacketType.Value) extends PacketBuilde override protected def packet = { flush() - new FMLProxyPacket(new PacketBuffer(Unpooled.wrappedBuffer(stream.toByteArray)), "OpenComputers") + stream.toByteArray } } @@ -106,7 +112,7 @@ class CompressedPacketBuilder(val packetType: PacketType.Value, private val data override protected def packet = { flush() stream.finish() - new FMLProxyPacket(new PacketBuffer(Unpooled.wrappedBuffer(data.toByteArray)), "OpenComputers") + data.toByteArray } } diff --git a/src/main/scala/li/cil/oc/common/PacketHandler.scala b/src/main/scala/li/cil/oc/common/PacketHandler.scala index 9b32860ca0..2f5d3ec1a4 100644 --- a/src/main/scala/li/cil/oc/common/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/common/PacketHandler.scala @@ -1,58 +1,56 @@ package li.cil.oc.common +import java.io.ByteArrayInputStream import java.io.DataInputStream import java.io.InputStream import java.util.zip.InflaterInputStream -import io.netty.buffer.ByteBuf -import io.netty.buffer.ByteBufInputStream import li.cil.oc.Constants import li.cil.oc.OpenComputers import li.cil.oc.api import li.cil.oc.common.block.RobotAfterimage import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP +import li.cil.oc.util.RotationHelper +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.network.INetHandler -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.ResourceLocation import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import net.minecraftforge.fml.common.FMLCommonHandler +import net.minecraftforge.fml.network.NetworkDirection +import net.minecraftforge.fml.server.ServerLifecycleHooks +import net.minecraftforge.registries._ +import scala.collection.mutable.ArrayBuffer import scala.reflect.ClassTag import scala.reflect.classTag -abstract class PacketHandler { - /** Top level dispatcher based on packet type. */ - protected def onPacketData(handler: INetHandler, data: ByteBuf, player: EntityPlayer) { - val thread = FMLCommonHandler.instance.getWorldThread(handler) - if (thread.isCallingFromMinecraftThread) { - process(data, player) - } - else { - data.retain() - thread.addScheduledTask(new Runnable { - override def run(): Unit = { - process(data, player) - data.release() - } - }) - } - } +object PacketHandler { + var clientHandler: PacketHandler = _ + + var serverHandler: PacketHandler = _ - private def process(data: ByteBuf, player: EntityPlayer): Unit = { - // Don't crash on badly formatted packets (may have been altered by a - // malicious client, in which case we don't want to allow it to kill the - // server like this). Just spam the log a bit... ;) + private[oc] def handlePacket(side: NetworkDirection, arr: Array[Byte], player: PlayerEntity): Unit = { try { - val stream = new ByteBufInputStream(data) - if (stream.read() == 0) dispatch(new PacketParser(stream, player)) - else dispatch(new PacketParser(new InflaterInputStream(stream), player)) + val handler = side match { + case NetworkDirection.PLAY_TO_CLIENT => clientHandler + case NetworkDirection.PLAY_TO_SERVER => serverHandler + case _ => null + } + if (handler != null) { + val stream = new ByteArrayInputStream(arr) + if (stream.read() == 0) handler.dispatch(handler.createParser(stream, player)) + else handler.dispatch(handler.createParser(new InflaterInputStream(stream), player)) + } } catch { + // Don't crash on badly formatted packets (may have been altered by a + // malicious client, in which case we don't want to allow it to kill the + // server like this). Just spam the log a bit... ;) case e: Throwable => OpenComputers.log.warn("Received a badly formatted packet.", e) } @@ -60,11 +58,13 @@ abstract class PacketHandler { // Avoid AFK kicks by marking players as non-idle when they send packets. // This will usually be stuff like typing while in screen GUIs. player match { - case mp: EntityPlayerMP => mp.markPlayerActive() - case _ => // Uh... OK? + case mp: ServerPlayerEntity => mp.resetLastActionTime() + case _ => } } +} +abstract class PacketHandler { /** * Gets the world for the specified dimension. * @@ -72,17 +72,22 @@ abstract class PacketHandler { * dimension; None otherwise. For the server it returns the world for the * specified dimension, if such a dimension exists; None otherwise. */ - protected def world(player: EntityPlayer, dimension: Int): Option[World] + protected def world(player: PlayerEntity, dimension: ResourceLocation): Option[World] protected def dispatch(p: PacketParser): Unit - protected class PacketParser(stream: InputStream, val player: EntityPlayer) extends DataInputStream(stream) { + protected def createParser(stream: InputStream, player: PlayerEntity): PacketParser + + private[oc] class PacketParser(stream: InputStream, val player: PlayerEntity) extends DataInputStream(stream) { val packetType = PacketType(readByte()) - def getTileEntity[T: ClassTag](dimension: Int, x: Int, y: Int, z: Int): Option[T] = { + def readRegistryEntry[T <: IForgeRegistryEntry[T]](registry: IForgeRegistry[T]): T = + registry.asInstanceOf[ForgeRegistry[T]].getValue(readInt()) + + def getBlockEntity[T: ClassTag](dimension: ResourceLocation, x: Int, y: Int, z: Int): Option[T] = { world(player, dimension) match { case Some(world) if world.blockExists(BlockPosition(x, y, z)) => - val t = world.getTileEntity(BlockPosition(x, y, z)) + val t = world.getBlockEntity(BlockPosition(x, y, z)) if (t != null && classTag[T].runtimeClass.isAssignableFrom(t.getClass)) { return Some(t.asInstanceOf[T]) } @@ -102,10 +107,10 @@ abstract class PacketHandler { None } - def getEntity[T: ClassTag](dimension: Int, id: Int): Option[T] = { + def getEntity[T: ClassTag](dimension: ResourceLocation, id: Int): Option[T] = { world(player, dimension) match { case Some(world) => - val e = world.getEntityByID(id) + val e = world.getEntity(id) if (e != null && classTag[T].runtimeClass.isAssignableFrom(e.getClass)) { return Some(e.asInstanceOf[T]) } @@ -114,34 +119,34 @@ abstract class PacketHandler { None } - def readTileEntity[T: ClassTag](): Option[T] = { - val dimension = readInt() + def readBlockEntity[T: ClassTag](): Option[T] = { + val dimension = new ResourceLocation(readUTF()) val x = readInt() val y = readInt() val z = readInt() - getTileEntity(dimension, x, y, z) + getBlockEntity(dimension, x, y, z) } def readEntity[T: ClassTag](): Option[T] = { - val dimension = readInt() + val dimension = new ResourceLocation(readUTF()) val id = readInt() getEntity[T](dimension, id) } - def readDirection(): Option[EnumFacing] = readByte() match { + def readDirection(): Option[Direction] = readByte() match { case id if id < 0 => None - case id => Option(EnumFacing.getFront(id)) + case id => Option(Direction.from3DDataValue(id)) } def readItemStack(): ItemStack = { val haveStack = readBoolean() if (haveStack) { - new ItemStack(readNBT()) + ItemStack.of(readNBT()) } else ItemStack.EMPTY } - def readNBT(): NBTTagCompound = { + def readNBT(): CompoundNBT = { val haveNbt = readBoolean() if (haveNbt) { CompressedStreamTools.read(this) @@ -151,5 +156,4 @@ abstract class PacketHandler { def readPacketType() = PacketType(readByte()) } - } diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala index eaa0ca14ad..2e8728bb13 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -81,6 +81,7 @@ object PacketType extends Enumeration { DronePower, KeyDown, KeyUp, + TextInput, Clipboard, MachineItemStateRequest, MachineItemStateResponse, diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index 72c1b90ab8..9f7585da5b 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -1,70 +1,63 @@ package li.cil.oc.common -import java.io.File +import java.util.function.Supplier import com.google.common.base.Strings import li.cil.oc._ +import li.cil.oc.common.{PacketHandler => CommonPacketHandler} import li.cil.oc.common.capabilities.Capabilities +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.entity.Drone +import li.cil.oc.common.entity.EntityTypes import li.cil.oc.common.init.Blocks import li.cil.oc.common.init.Items -import li.cil.oc.common.item.Delegator -import li.cil.oc.common.item.traits.Delegate -import li.cil.oc.common.recipe.Recipes +import li.cil.oc.common.tileentity.TileEntityTypes +import li.cil.oc.common.recipe.RecipeSerializers import li.cil.oc.integration.Mods +import li.cil.oc.server import li.cil.oc.server._ +import li.cil.oc.server.loot.LootFunctions import li.cil.oc.server.machine.luac.LuaStateFactory import li.cil.oc.server.machine.luac.NativeLua52Architecture import li.cil.oc.server.machine.luac.NativeLua53Architecture import li.cil.oc.server.machine.luaj.LuaJLuaArchitecture import net.minecraft.block.Block +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.inventory.container.Container +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.network.PacketBuffer +import net.minecraft.tags.ItemTags import net.minecraft.util.ResourceLocation +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.World import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.event.RegistryEvent.MissingMappings -import net.minecraftforge.fml.common.FMLLog -import net.minecraftforge.fml.common.event._ -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.network.NetworkRegistry -import net.minecraftforge.fml.common.registry.{EntityRegistry} -import net.minecraftforge.oredict.OreDictionary - -import scala.collection.convert.WrapAsScala._ +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent +import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent +import net.minecraftforge.fml.network.NetworkEvent +import net.minecraftforge.fml.network.NetworkRegistry +import net.minecraftforge.registries.ForgeRegistries +import net.minecraftforge.scorge.lang.ScorgeModLoadingContext + +import scala.jdk.CollectionConverters._ import scala.reflect.ClassTag class Proxy { - def preInit(e: FMLPreInitializationEvent) { - checkForBrokenJavaVersion() - - Settings.load(new File(e.getModConfigurationDirectory, "opencomputers" + File.separator + "settings.conf")) - - MinecraftForge.EVENT_BUS.register(this) - - OpenComputers.log.debug("Initializing blocks and items.") - - Blocks.init() - Items.init() - - OpenComputers.log.debug("Initializing additional OreDict entries.") - - OreDictionary.registerOre("craftingPiston", net.minecraft.init.Blocks.PISTON) - OreDictionary.registerOre("craftingPiston", net.minecraft.init.Blocks.STICKY_PISTON) - OreDictionary.registerOre("torchRedstoneActive", net.minecraft.init.Blocks.REDSTONE_TORCH) - OreDictionary.registerOre("materialEnderPearl", net.minecraft.init.Items.ENDER_PEARL) - - // Make mods that use old wireless card name not have broken recipes - OreDictionary.registerOre("oc:wlanCard", Items.get(Constants.ItemName.WirelessNetworkCardTier2).createItemStack(1)) - - tryRegisterNugget[item.DiamondChip](Constants.ItemName.DiamondChip, "chipDiamond", net.minecraft.init.Items.DIAMOND, "gemDiamond") - - // Avoid issues with Extra Utilities registering colored obsidian as `obsidian` - // oredict entry, but not normal obsidian, breaking some recipes. - OreDictionary.registerOre("obsidian", net.minecraft.init.Blocks.OBSIDIAN) - - // To still allow using normal endstone for crafting drones. - OreDictionary.registerOre("oc:stoneEndstone", net.minecraft.init.Blocks.END_STONE) - + protected val modBus = ScorgeModLoadingContext.get.getModEventBus + modBus.register(classOf[ContainerTypes]) + modBus.register(classOf[EntityTypes]) + modBus.register(classOf[TileEntityTypes]) + modBus.register(classOf[RecipeSerializers]) + LootFunctions.init() + + def preInit() { OpenComputers.log.info("Initializing OpenComputers API.") api.CreativeTab.instance = CreativeTab @@ -98,67 +91,45 @@ class Proxy { api.Machine.LuaArchitecture = if (Settings.get.forceLuaJ) classOf[LuaJLuaArchitecture] - else api.Machine.architectures.head + else api.Machine.architectures.asScala.head } - def init(e: FMLInitializationEvent) { - OpenComputers.channel = NetworkRegistry.INSTANCE.newEventDrivenChannel("OpenComputers") - OpenComputers.channel.register(server.PacketHandler) - - Loot.init() - Achievement.init() - - EntityRegistry.registerModEntity(new ResourceLocation(Settings.resourceDomain, "drone"), classOf[Drone], "Drone", 0, OpenComputers, 80, 1, true) - - OpenComputers.log.debug("Initializing mod integration.") - Mods.init() - - OpenComputers.log.debug("Initializing recipes.") - Recipes.init() - - OpenComputers.log.info("Initializing capabilities.") - Capabilities.init() - - api.API.isPowerEnabled = !Settings.get.ignorePower + @SubscribeEvent + def init(e: FMLCommonSetupEvent) { + e.enqueueWork((() => { + OpenComputers.channel = NetworkRegistry.newSimpleChannel(new ResourceLocation(OpenComputers.ID, "net_main"), () => "", "".equals(_), "".equals(_)) + OpenComputers.channel.registerMessage(0, classOf[Array[Byte]], + (msg: Array[Byte], buff: PacketBuffer) => buff.writeByteArray(msg), _.readByteArray(), + (msg: Array[Byte], ctx: Supplier[NetworkEvent.Context]) => { + val context = ctx.get + context.enqueueWork(() => CommonPacketHandler.handlePacket(context.getDirection, msg, context.getSender)) + context.setPacketHandled(true) + }) + CommonPacketHandler.serverHandler = server.PacketHandler + + Loot.init() + Achievement.init() + + OpenComputers.log.debug("Initializing mod integration.") + Mods.init() + + OpenComputers.log.info("Initializing capabilities.") + Capabilities.init() + + api.API.isPowerEnabled = !Settings.get.ignorePower + }): Runnable) } - def postInit(e: FMLPostInitializationEvent) { + @SubscribeEvent + def postInit(e: FMLLoadCompleteEvent) { // Don't allow driver registration after this point, to avoid issues. driver.Registry.locked = true } - def tryRegisterNugget[TItem <: Delegate : ClassTag](nuggetItemName: String, nuggetOredictName: String, ingotItem: Item, ingotOredictName: String): Unit = { - val nugget = Items.get(nuggetItemName).createItemStack(1) - - registerExclusive(nuggetOredictName, nugget) - - Delegator.subItem(nugget) match { - case Some(subItem: TItem) => - if (OreDictionary.getOres(nuggetOredictName).exists(nugget.isItemEqual)) { - Recipes.addSubItem(subItem, nuggetItemName) - Recipes.addItem(ingotItem, ingotOredictName) - } - else { - subItem.showInItemList = false - } - case _ => - } - } - - def registerModel(instance: Delegate, id: String): Unit = {} - def registerModel(instance: Item, id: String): Unit = {} def registerModel(instance: Block, id: String): Unit = {} - private def registerExclusive(name: String, items: ItemStack*) { - if (OreDictionary.getOres(name).isEmpty) { - for (item <- items) { - OreDictionary.registerOre(name, item) - } - } - } - // Yes, this could be boiled down even further, but I like to keep it // explicit like this, because it makes it a) clearer, b) easier to // extend, in case that should ever be needed. @@ -177,11 +148,11 @@ class Proxy { @SubscribeEvent def missingBlockMappings(e: MissingMappings[Block]) { - for (missing <- e.getMappings) { - blockRenames.get(missing.key.getResourcePath) match { + for (missing <- e.getMappings(OpenComputers.ID).asScala) { + blockRenames.get(missing.key.getPath) match { case Some(name) => if (Strings.isNullOrEmpty(name)) missing.ignore() - else missing.remap(Block.REGISTRY.getObject(new ResourceLocation(OpenComputers.ID, name))) + else missing.remap(ForgeRegistries.BLOCKS.getValue(new ResourceLocation(OpenComputers.ID, name))) case _ => missing.warn() } } @@ -189,27 +160,13 @@ class Proxy { @SubscribeEvent def missingItemMappings(e: MissingMappings[Item]) { - for (missing <- e.getMappings) { - itemRenames.get(missing.key.getResourcePath) match { + for (missing <- e.getMappings(OpenComputers.ID).asScala) { + itemRenames.get(missing.key.getPath) match { case Some(name) => if (Strings.isNullOrEmpty(name)) missing.ignore() - else missing.remap(Item.REGISTRY.getObject(new ResourceLocation(OpenComputers.ID, name))) + else missing.remap(ForgeRegistries.ITEMS.getValue(new ResourceLocation(OpenComputers.ID, name))) case _ => missing.warn() } } } - - // OK, seriously now, I've gotten one too many bug reports because of this Java version being broken. - - private final val BrokenJavaVersions = Set("1.6.0_65, Apple Inc.") - - def isBrokenJavaVersion = { - val javaVersion = System.getProperty("java.version") + ", " + System.getProperty("java.vendor") - BrokenJavaVersions.contains(javaVersion) - } - - def checkForBrokenJavaVersion() = if (isBrokenJavaVersion) { - FMLLog.bigWarning("You're using a broken Java version! Please update now, or remove OpenComputers. DO NOT REPORT THIS! UPDATE YOUR JAVA!") - throw new Exception("You're using a broken Java version! Please update now, or remove OpenComputers. DO NOT REPORT THIS! UPDATE YOUR JAVA!") - } } diff --git a/src/main/scala/li/cil/oc/common/SaveHandler.scala b/src/main/scala/li/cil/oc/common/SaveHandler.scala index 5dfd4bc9ce..332277d699 100644 --- a/src/main/scala/li/cil/oc/common/SaveHandler.scala +++ b/src/main/scala/li/cil/oc/common/SaveHandler.scala @@ -18,13 +18,15 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.SafeThreadPool import li.cil.oc.util.ThreadPoolFactory import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.ResourceLocation import net.minecraft.util.math.ChunkPos import net.minecraft.world.World -import net.minecraftforge.common.DimensionManager +import net.minecraft.world.storage.FolderName import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.EventPriority +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fml.server.ServerLifecycleHooks import org.apache.commons.lang3.JavaVersion import org.apache.commons.lang3.SystemUtils @@ -48,10 +50,10 @@ object SaveHandler { // which takes a lot of time and is completely unnecessary in those cases. var savingForClients = false - class SaveDataEntry(val data: Array[Byte], val pos: ChunkPos, val name: String, val dimension: Int) extends Runnable { + class SaveDataEntry(val data: Array[Byte], val pos: ChunkPos, val name: String, val dimension: ResourceLocation) extends Runnable { override def run(): Unit = { val path = statePath - val dimPath = new io.File(path, dimension.toString) + val dimPath = new io.File(path, dimension.toString.replace(':', '/').replace('.', '/')) val chunkPath = new io.File(dimPath, s"${this.pos.x}.${this.pos.z}") chunkDirs.add(chunkPath) if (!chunkPath.exists()) { @@ -75,46 +77,46 @@ object SaveHandler { val chunkDirs = new ConcurrentLinkedDeque[io.File]() val saving = mutable.HashMap.empty[String, Future[_]] - def savePath = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath) + def savePath = ServerLifecycleHooks.getCurrentServer.getWorldPath(new FolderName(Settings.savePath)).toFile def statePath = new io.File(savePath, "state") - def scheduleSave(host: MachineHost, nbt: NBTTagCompound, name: String, data: Array[Byte]) { + def scheduleSave(host: MachineHost, nbt: CompoundNBT, name: String, data: Array[Byte]) { scheduleSave(BlockPosition(host), nbt, name, data) } - def scheduleSave(host: MachineHost, nbt: NBTTagCompound, name: String, save: NBTTagCompound => Unit) { + def scheduleSave(host: MachineHost, nbt: CompoundNBT, name: String, save: CompoundNBT => Unit) { scheduleSave(host, nbt, name, writeNBT(save)) } - def scheduleSave(host: EnvironmentHost, nbt: NBTTagCompound, name: String, save: NBTTagCompound => Unit) { + def scheduleSave(host: EnvironmentHost, nbt: CompoundNBT, name: String, save: CompoundNBT => Unit) { scheduleSave(BlockPosition(host), nbt, name, writeNBT(save)) } - def scheduleSave(world: World, x: Double, z: Double, nbt: NBTTagCompound, name: String, data: Array[Byte]) { + def scheduleSave(world: World, x: Double, z: Double, nbt: CompoundNBT, name: String, data: Array[Byte]) { scheduleSave(BlockPosition(x, 0, z, world), nbt, name, data) } - def scheduleSave(world: World, x: Double, z: Double, nbt: NBTTagCompound, name: String, save: NBTTagCompound => Unit) { + def scheduleSave(world: World, x: Double, z: Double, nbt: CompoundNBT, name: String, save: CompoundNBT => Unit) { scheduleSave(world, x, z, nbt, name, writeNBT(save)) } - def scheduleSave(position: BlockPosition, nbt: NBTTagCompound, name: String, data: Array[Byte]) { + def scheduleSave(position: BlockPosition, nbt: CompoundNBT, name: String, data: Array[Byte]) { val world = position.world.get - val dimension = world.provider.getDimension + val dimension = world.dimension.location val chunk = new ChunkPos(position.x >> 4, position.z >> 4) // We have to save the dimension and chunk coordinates, because they are // not available on load / may have changed if the computer was moved. - nbt.setInteger("dimension", dimension) - nbt.setInteger("chunkX", chunk.x) - nbt.setInteger("chunkZ", chunk.z) + nbt.putString("dimension", dimension.toString) + nbt.putInt("chunkX", chunk.x) + nbt.putInt("chunkZ", chunk.z) scheduleSave(dimension, chunk, name, data) } - private def writeNBT(save: NBTTagCompound => Unit) = { - val tmpNbt = new NBTTagCompound() + private def writeNBT(save: CompoundNBT => Unit) = { + val tmpNbt = new CompoundNBT() save(tmpNbt) val baos = new ByteArrayOutputStream() val dos = new DataOutputStream(baos) @@ -122,7 +124,7 @@ object SaveHandler { baos.toByteArray } - def loadNBT(nbt: NBTTagCompound, name: String): NBTTagCompound = { + def loadNBT(nbt: CompoundNBT, name: String): CompoundNBT = { val data = load(nbt, name) if (data.length > 0) try { val bais = new ByteArrayInputStream(data) @@ -132,17 +134,17 @@ object SaveHandler { catch { case t: Throwable => OpenComputers.log.warn("There was an error trying to restore a block's state from external data. This indicates that data was somehow corrupted.", t) - new NBTTagCompound() + new CompoundNBT() } - else new NBTTagCompound() + else new CompoundNBT() } - def load(nbt: NBTTagCompound, name: String): Array[Byte] = { + def load(nbt: CompoundNBT, name: String): Array[Byte] = { // Since we have no world yet, we rely on the dimension we were saved in. // Same goes for the chunk. This also works around issues with computers // being moved (e.g. Redstone in Motion). - val dimension = nbt.getInteger("dimension") - val chunk = new ChunkPos(nbt.getInteger("chunkX"), nbt.getInteger("chunkZ")) + val dimension = nbt.getString("dimension") + val chunk = new ChunkPos(nbt.getInt("chunkX"), nbt.getInt("chunkZ")) // Wait for the latest save task for the requested file to complete. // This prevents the chance of loading an outdated version @@ -155,10 +157,10 @@ object SaveHandler { }) saving.remove(name) - load(dimension, chunk, name) + load(new ResourceLocation(dimension), chunk, name) } - def scheduleSave(dimension: Int, chunk: ChunkPos, name: String, data: Array[Byte]): Unit = { + def scheduleSave(dimension: ResourceLocation, chunk: ChunkPos, name: String, data: Array[Byte]): Unit = { if (chunk == null) throw new IllegalArgumentException("chunk is null") else { // Disregarding whether or not there already was a @@ -169,11 +171,11 @@ object SaveHandler { } } - def load(dimension: Int, chunk: ChunkPos, name: String): Array[Byte] = { + def load(dimension: ResourceLocation, chunk: ChunkPos, name: String): Array[Byte] = { if (chunk == null) throw new IllegalArgumentException("chunk is null") val path = statePath - val dimPath = new io.File(path, dimension.toString) + val dimPath = new io.File(path, dimension.toString.replace(':', '/').replace('.', '/')) val chunkPath = new io.File(dimPath, s"${chunk.x}.${chunk.z}") val file = new io.File(chunkPath, name) if (!file.exists()) return Array.empty[Byte] @@ -219,7 +221,7 @@ object SaveHandler { @SubscribeEvent(priority = EventPriority.HIGHEST) def onWorldLoad(e: WorldEvent.Load) { - if (!e.getWorld.isRemote) { + if (!e.getWorld.isClientSide) { // Touch all externally saved data when loading, to avoid it getting // deleted in the next save (because the now - save time will usually // be larger than the time out after loading a world again). diff --git a/src/main/scala/li/cil/oc/common/ToolDurabilityProviders.scala b/src/main/scala/li/cil/oc/common/ToolDurabilityProviders.scala index 23b6dda932..20d0a65c05 100644 --- a/src/main/scala/li/cil/oc/common/ToolDurabilityProviders.scala +++ b/src/main/scala/li/cil/oc/common/ToolDurabilityProviders.scala @@ -17,7 +17,7 @@ object ToolDurabilityProviders { if (!durability.isNaN) return Option(durability) } // Fall back to vanilla damage values. - if (stack.isItemStackDamageable) Option(1.0 - stack.getItemDamage.toDouble / stack.getMaxDamage.toDouble) + if (stack.getItem.canBeDepleted) Option(1.0 - stack.getDamageValue.toDouble / stack.getMaxDamage.toDouble) else None } } diff --git a/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala b/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala deleted file mode 100644 index ff9c1aa9d3..0000000000 --- a/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala +++ /dev/null @@ -1,415 +0,0 @@ -package li.cil.oc.common.asm - -import li.cil.oc.common.asm.template.SimpleComponentImpl -import li.cil.oc.integration.Mods -import net.minecraft.launchwrapper.IClassTransformer -import net.minecraft.launchwrapper.LaunchClassLoader -import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper -import org.apache.logging.log4j.LogManager -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassWriter -import org.objectweb.asm.Opcodes -import org.objectweb.asm.tree._ - -import scala.annotation.tailrec -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ - -object ObfNames { - final val Class_EntityHanging = Array("net/minecraft/entity/EntityHanging") - final val Class_EntityLiving = Array("net/minecraft/entity/EntityLiving") - final val Class_RenderLiving = Array("net/minecraft/client/renderer/entity/RenderLiving") - final val Class_TileEntity = Array("net/minecraft/tileentity/TileEntity") - final val Field_leashNBTTag = Array("leashNBTTag", "field_110170_bx") - final val Field_leashedToEntity = Array("leashedToEntity", "leashHolder", "field_110168_bw") - final val Method_recreateLeash = Array("recreateLeash", "func_110165_bF") - final val Method_recreateLeashDesc = Array("()V") - final val Method_renderLeash = Array("renderLeash", "func_110827_b") - final val Method_renderLeashDesc = Array("(Lnet/minecraft/entity/EntityLiving;DDDFF)V") - final val Method_validate = Array("validate", "func_145829_t") - final val Method_invalidate = Array("invalidate", "func_145843_s") - final val Method_onChunkUnload = Array("onChunkUnload", "func_76623_d") - final val Method_readFromNBT = Array("readFromNBT", "func_145839_a") - final val Method_writeToNBT = Array("writeToNBT", "func_189515_b") -} - -object ClassTransformer { - var hadErrors = false - var hadSimpleComponentErrors = false -} - -class ClassTransformer extends IClassTransformer { - private val loader = classOf[ClassTransformer].getClassLoader.asInstanceOf[LaunchClassLoader] - private val log = LogManager.getLogger("OpenComputers") - - override def transform(obfName: String, name: String, basicClass: Array[Byte]): Array[Byte] = { - if (basicClass == null || name.startsWith("scala.")) return basicClass - var transformedClass = basicClass - try { - if (!name.startsWith("net.minecraft.") - && !name.startsWith("net.minecraftforge.") - && !name.startsWith("li.cil.oc.common.asm.") - && !name.startsWith("li.cil.oc.integration.")) { - if (name.startsWith("li.cil.oc.")) { - // Strip foreign interfaces from scala generated classes. This is - // primarily intended to clean up mix-ins / synthetic classes - // generated by Scala. - val classNode = newClassNode(transformedClass) - val missingInterfaces = classNode.interfaces.filter(!classExists(_)) - for (interfaceName <- missingInterfaces) { - log.trace(s"Stripping interface $interfaceName from class $name because it is missing.") - } - classNode.interfaces.removeAll(missingInterfaces) - - val missingClasses = classNode.innerClasses.filter(clazz => clazz.outerName != null && !classExists(clazz.outerName)) - for (innerClass <- missingClasses) { - log.trace(s"Stripping inner class ${innerClass.name} from class $name because its type ${innerClass.outerName} is missing.") - } - classNode.innerClasses.removeAll(missingClasses) - - val incompleteMethods = classNode.methods.filter(method => missingFromSignature(method.desc).nonEmpty) - for (method <- incompleteMethods) { - val missing = missingFromSignature(method.desc).mkString(", ") - log.trace(s"Stripping method ${method.name} from class $name because the following types in its signature are missing: $missing") - } - classNode.methods.removeAll(incompleteMethods) - - // Inject available interfaces where requested. - if (classNode.visibleAnnotations != null) { - def injectInterface(annotation: AnnotationNode): Unit = { - val values = annotation.values.grouped(2).map(buffer => buffer.head -> buffer.last).toMap - (values.get("value"), values.get("modid")) match { - case (Some(interfaceName: String), Some(modid: String)) => - Mods.All.find(_.id == modid) match { - case Some(mod) => - if (mod.isModAvailable) { - val interfaceDesc = interfaceName.replaceAllLiterally(".", "/") - val node = classNodeFor(interfaceDesc) - if (node == null) { - log.warn(s"Interface $interfaceName not found, skipping injection.") - } - else { - val missing = node.methods.filterNot(im => classNode.methods.exists(cm => im.name == cm.name && im.desc == cm.desc)).map(method => s"Missing implementation of ${method.name + method.desc}") - if (missing.isEmpty) { - log.info(s"Injecting interface $interfaceName into $name.") - classNode.interfaces.add(interfaceDesc) - } - else { - log.warn(s"Missing implementations for interface $interfaceName, skipping injection.") - missing.foreach(log.warn) - ClassTransformer.hadErrors = true - } - } - } - else { - log.info(s"Skipping interface $interfaceName from missing mod $modid.") - } - case _ => - log.warn(s"Skipping interface $interfaceName from unknown mod $modid.") - ClassTransformer.hadErrors = true - } - case _ => - } - } - classNode.visibleAnnotations.find(_.desc == "Lli/cil/oc/common/asm/Injectable$Interface;") match { - case Some(annotation) => - injectInterface(annotation) - case _ => - } - classNode.visibleAnnotations.find(_.desc == "Lli/cil/oc/common/asm/Injectable$InterfaceList;") match { - case Some(annotation) => - val values = annotation.values.grouped(2).map(buffer => buffer.head -> buffer.last).toMap - values.get("value") match { - case Some(interfaceList: java.lang.Iterable[AnnotationNode]@unchecked) => - interfaceList.foreach(injectInterface) - case _ => - } - case _ => - } - } - - transformedClass = writeClass(classNode) - } - { - val classNode = newClassNode(transformedClass) - if (classNode.interfaces.contains("li/cil/oc/api/network/SimpleComponent") && - (classNode.visibleAnnotations == null || !classNode.visibleAnnotations. - exists(annotation => annotation != null && annotation.desc == "Lli/cil/oc/api/network/SimpleComponent$SkipInjection;"))) { - try { - transformedClass = injectEnvironmentImplementation(classNode) - log.info(s"Successfully injected component logic into class $name.") - } - catch { - case e: Throwable => - log.warn(s"Failed injecting component logic into class $name.", e) - ClassTransformer.hadSimpleComponentErrors = true - } - } - } - } - - // Inject some code into the EntityLiving classes recreateLeash method to allow - // proper loading of leashes tied to entities using the leash upgrade. This is - // necessary because entities only save the entity they are leashed to if that - // entity is an EntityLivingBase - which drones, for example, are not, for good - // reason. We work around this by re-leashing them in the load method of the - // leash upgrade. The leashed entity would then still unleash itself and, more - // problematically drop a leash item. To avoid this, we extend the - // if (this.isLeashed && this.field_110170_bx != null) - // check to read - // if (this.isLeashed && this.field_110170_bx != null && this.leashedToEntity == null) - // which should not interfere with any existing logic, but avoid leashing - // restored manually in the load phase to not be broken again. - if (ObfNames.Class_EntityLiving.contains(name.replace('.', '/'))) { - val classNode = newClassNode(transformedClass) - insertInto(classNode, ObfNames.Method_recreateLeash, ObfNames.Method_recreateLeashDesc, instructions => instructions.toArray.sliding(3, 1).exists { - case Array(varNode: VarInsnNode, fieldNode: FieldInsnNode, jumpNode: JumpInsnNode) - if varNode.getOpcode == Opcodes.ALOAD && varNode.`var` == 0 && - fieldNode.getOpcode == Opcodes.GETFIELD && ObfNames.Field_leashNBTTag.contains(fieldNode.name) && - jumpNode.getOpcode == Opcodes.IFNULL => - classNode.fields.find(field => ObfNames.Field_leashedToEntity.contains(field.name)) match { - case Some(field) => - val toInject = new InsnList() - toInject.add(new VarInsnNode(Opcodes.ALOAD, 0)) - toInject.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, field.name, field.desc)) - toInject.add(new JumpInsnNode(Opcodes.IFNONNULL, jumpNode.label)) - instructions.insert(jumpNode, toInject) - true - case _ => - false - } - case _ => - false - }) match { - case Some(data) => transformedClass = data - case _ => - } - } - - // Little change to the renderer used to render leashes to center it on drones. - // This injects the code - // if (entity instanceof Drone) { - // d5 = 0.0; - // d6 = 0.0; - // d7 = -0.25; - // } - // before the `instanceof EntityHanging` check in func_110827_b. - if (ObfNames.Class_RenderLiving.contains(name.replace('.', '/'))) { - val classNode = newClassNode(transformedClass) - insertInto(classNode, ObfNames.Method_renderLeash, ObfNames.Method_renderLeashDesc, instructions => instructions.toArray.sliding(3, 1).exists { - case Array(varNode: VarInsnNode, typeNode: TypeInsnNode, jumpNode: JumpInsnNode) - if varNode.getOpcode == Opcodes.ALOAD && varNode.`var` == 10 && - typeNode.getOpcode == Opcodes.INSTANCEOF && ObfNames.Class_EntityHanging.contains(typeNode.desc) && - jumpNode.getOpcode == Opcodes.IFEQ => - val toInject = new InsnList() - toInject.add(new VarInsnNode(Opcodes.ALOAD, 10)) - toInject.add(new TypeInsnNode(Opcodes.INSTANCEOF, "li/cil/oc/common/entity/Drone")) - val skip = new LabelNode() - toInject.add(new JumpInsnNode(Opcodes.IFEQ, skip)) - toInject.add(new LdcInsnNode(Double.box(0.0))) - toInject.add(new VarInsnNode(Opcodes.DSTORE, 17)) - toInject.add(new LdcInsnNode(Double.box(0.0))) - toInject.add(new VarInsnNode(Opcodes.DSTORE, 19)) - toInject.add(new LdcInsnNode(Double.box(-0.25))) - toInject.add(new VarInsnNode(Opcodes.DSTORE, 21)) - toInject.add(skip) - instructions.insertBefore(varNode, toInject) - true - case _ => - false - }) match { - case Some(data) => transformedClass = data - case _ => - } - } - - transformedClass - } - catch { - case t: Throwable => - log.warn("Something went wrong!", t) - ClassTransformer.hadErrors = true - basicClass - } - } - - private def insertInto(classNode: ClassNode, methodNames: Array[String], methodDescs: Array[String], inserter: (InsnList) => Boolean): Option[Array[Byte]] = { - classNode.methods.find(method => methodNames.contains(method.name) && methodDescs.contains(method.desc)) match { - case Some(methodNode) => - if (inserter(methodNode.instructions)) { - log.info(s"Successfully patched ${classNode.name}.${methodNames(0)}.") - Option(writeClass(classNode, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES)) - } - else { - log.warn(s"Failed patching ${classNode.name}.${methodNames(0)}, injection point not found.") - ClassTransformer.hadErrors = true - None - } - case _ => - log.warn(s"Failed patching ${classNode.name}.${methodNames(0)}, method not found.") - ClassTransformer.hadErrors = true - None - } - } - - private def classExists(name: String) = { - loader.getClassBytes(name) != null || - loader.getClassBytes(FMLDeobfuscatingRemapper.INSTANCE.unmap(name)) != null || - (try loader.findClass(name.replace('/', '.')) != null catch { - case _: ClassNotFoundException => false - }) - } - - private def missingFromSignature(desc: String) = { - """L([^;]+);""".r.findAllMatchIn(desc).map(_.group(1)).filter(!classExists(_)) - } - - def injectEnvironmentImplementation(classNode: ClassNode): Array[Byte] = { - log.trace(s"Injecting methods from Environment interface into ${classNode.name}.") - if (!isTileEntity(classNode)) { - throw new InjectionFailedException("Found SimpleComponent on something that isn't a tile entity, ignoring.") - } - - val template = classNodeFor("li/cil/oc/common/asm/template/SimpleEnvironment") - if (template == null) { - throw new InjectionFailedException("Could not find SimpleComponent template!") - } - - def inject(methodName: String, signature: String, required: Boolean = false) { - def filter(method: MethodNode) = method.name == methodName && method.desc == signature - if (classNode.methods.exists(filter)) { - if (required) { - throw new InjectionFailedException(s"Could not inject method '$methodName$signature' because it was already present!") - } - } - else template.methods.find(filter) match { - case Some(method) => classNode.methods.add(method) - case _ => throw new AssertionError() - } - } - inject("node", "()Lli/cil/oc/api/network/Node;", required = true) - inject("onConnect", "(Lli/cil/oc/api/network/Node;)V") - inject("onDisconnect", "(Lli/cil/oc/api/network/Node;)V") - inject("onMessage", "(Lli/cil/oc/api/network/Message;)V") - - log.trace("Injecting / wrapping overrides for required tile entity methods.") - def replace(methodName: String, methodNameSrg: String, desc: String) { - val mapper = FMLDeobfuscatingRemapper.INSTANCE - def filter(method: MethodNode) = { - val descDeObf = mapper.mapMethodDesc(method.desc) - val methodNameDeObf = mapper.mapMethodName(mapper.unmap(ObfNames.Class_TileEntity(0)), method.name, method.desc) - val areSamePlain = method.name + descDeObf == methodName + desc - val areSameDeObf = methodNameDeObf + descDeObf == methodNameSrg + desc - areSamePlain || areSameDeObf - } - if (classNode.methods.exists(method => method.name == methodName + SimpleComponentImpl.PostFix && mapper.mapMethodDesc(method.desc) == desc)) { - throw new InjectionFailedException(s"Delegator method name '${methodName + SimpleComponentImpl.PostFix}' is already in use.") - } - classNode.methods.find(filter) match { - case Some(method) => - log.trace(s"Found original implementation of '$methodName', wrapping.") - method.name = methodName + SimpleComponentImpl.PostFix - case _ => - log.trace(s"No original implementation of '$methodName', will inject override.") - @tailrec def ensureNonFinalIn(name: String) { - if (name != null) { - val node = classNodeFor(name) - if (node != null) { - node.methods.find(filter) match { - case Some(method) => - if ((method.access & Opcodes.ACC_FINAL) != 0) { - throw new InjectionFailedException(s"Method '$methodName' is final in superclass ${node.name.replace('/', '.')}.") - } - case _ => - } - ensureNonFinalIn(node.superName) - } - } - } - ensureNonFinalIn(classNode.superName) - template.methods.find(_.name == methodName + SimpleComponentImpl.PostFix) match { - case Some(method) => classNode.methods.add(method) - case _ => throw new AssertionError(s"Couldn't find '${methodName + SimpleComponentImpl.PostFix}' in template implementation.") - } - } - template.methods.find(filter) match { - case Some(method) => classNode.methods.add(method) - case _ => throw new AssertionError(s"Couldn't find '$methodName' in template implementation.") - } - } - replace(ObfNames.Method_validate(0), ObfNames.Method_validate(1), "()V") - replace(ObfNames.Method_invalidate(0), ObfNames.Method_invalidate(1), "()V") - replace(ObfNames.Method_onChunkUnload(0), ObfNames.Method_onChunkUnload(1), "()V") - replace(ObfNames.Method_readFromNBT(0), ObfNames.Method_readFromNBT(1), "(Lnet/minecraft/nbt/NBTTagCompound;)V") - replace(ObfNames.Method_writeToNBT(0), ObfNames.Method_writeToNBT(1), "(Lnet/minecraft/nbt/NBTTagCompound;)Lnet/minecraft/nbt/NBTTagCompound;") - - log.trace("Injecting interface.") - classNode.interfaces.add("li/cil/oc/common/asm/template/SimpleComponentImpl") - - writeClass(classNode, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES) - } - - @tailrec final def isTileEntity(classNode: ClassNode): Boolean = { - if (classNode == null) false - else { - log.trace(s"Checking if class ${classNode.name} is a TileEntity...") - ObfNames.Class_TileEntity.contains(FMLDeobfuscatingRemapper.INSTANCE.map(classNode.name)) || - (classNode.superName != null && isTileEntity(classNodeFor(classNode.superName))) - } - } - - @tailrec final def isAssignable(parent: ClassNode, child: ClassNode): Boolean = parent != null && child != null && !isFinal(parent) && { - parent.name == "java/lang/Object" || - parent.name == child.name || - parent.name == child.superName || - child.interfaces.contains(parent.name) || - (child.superName != null && isAssignable(parent, classNodeFor(child.superName))) - } - - def isFinal(node: ClassNode): Boolean = (node.access & Opcodes.ACC_FINAL) != 0 - - def isInterface(node: ClassNode): Boolean = node != null && (node.access & Opcodes.ACC_INTERFACE) != 0 - - def classNodeFor(name: String) = { - val namePlain = name.replace('/', '.') - val bytes = loader.getClassBytes(namePlain) - if (bytes != null) newClassNode(bytes) - else { - val nameObfed = FMLDeobfuscatingRemapper.INSTANCE.unmap(name).replace('/', '.') - val bytes = loader.getClassBytes(nameObfed) - if (bytes == null) null - else newClassNode(bytes) - } - } - - def newClassNode(data: Array[Byte]) = { - val classNode = new ClassNode() - new ClassReader(data).accept(classNode, 0) - classNode - } - - def writeClass(classNode: ClassNode, flags: Int = ClassWriter.COMPUTE_MAXS) = { - val writer = new ClassWriter(flags) { - // Implementation without class loads, avoids https://github.com/MinecraftForge/FML/issues/655 - override def getCommonSuperClass(type1: String, type2: String): String = { - val node1 = classNodeFor(type1) - val node2 = classNodeFor(type2) - if (isAssignable(node1, node2)) node1.name - else if (isAssignable(node2, node1)) node2.name - else if (isInterface(node1) || isInterface(node2)) "java/lang/Object" - else { - var parent = Option(node1).map(_.superName).map(classNodeFor).orNull - while (parent != null && parent.superName != null && !isAssignable(parent, node2)) { - parent = classNodeFor(parent.superName) - } - if (parent == null) "java/lang/Object" else parent.name - } - } - } - classNode.accept(writer) - writer.toByteArray - } - - class InjectionFailedException(message: String) extends Exception(message) - -} diff --git a/src/main/scala/li/cil/oc/common/asm/Injectable.java b/src/main/scala/li/cil/oc/common/asm/Injectable.java deleted file mode 100644 index f08dba3208..0000000000 --- a/src/main/scala/li/cil/oc/common/asm/Injectable.java +++ /dev/null @@ -1,50 +0,0 @@ -package li.cil.oc.common.asm; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This interface is kind of the opposite to FML's Optional annotations. - *

    - * Instead of stripping interfaces if they are not present, it will inject them - * when they are present. This helps with some strange cases where - * stripping does not work as it should. - */ -public final class Injectable { - /** - * Not constructable. - */ - private Injectable() { - } - - /** - * Mark a list of interfaces as injectable. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface InterfaceList { - public Interface[] value(); - } - - /** - * Used to inject optional interfaces. - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.TYPE) - public @interface Interface { - /** - * The fully qualified name of the interface to inject. - */ - public String value(); - - /** - * The modid that is required to be present for the injecting to occur. - *

    - * Note that injection will not occur if the interface is not fully - * implemented. - */ - public String modid(); - } -} diff --git a/src/main/scala/li/cil/oc/common/block/Adapter.scala b/src/main/scala/li/cil/oc/common/block/Adapter.scala index 8f4e66152b..38c086d9df 100644 --- a/src/main/scala/li/cil/oc/common/block/Adapter.scala +++ b/src/main/scala/li/cil/oc/common/block/Adapter.scala @@ -1,53 +1,60 @@ package li.cil.oc.common.block -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.tileentity import li.cil.oc.integration.util.Wrench +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IBlockReader +import net.minecraft.world.IWorldReader import net.minecraft.world.World -class Adapter extends SimpleBlock with traits.GUI { - override def guiType = GuiType.Adapter +class Adapter(props: Properties) extends SimpleBlock(props) with traits.GUI { + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Adapter => ContainerTypes.openAdapterGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Adapter() + override def newBlockEntity(world: IBlockReader) = new tileentity.Adapter(tileentity.TileEntityTypes.ADAPTER) // ----------------------------------------------------------------------- // - override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit = - world.getTileEntity(pos) match { + @Deprecated + override def neighborChanged(state: BlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos, b: Boolean): Unit = + world.getBlockEntity(pos) match { case adapter: tileentity.Adapter => adapter.neighborChanged() case _ => // Ignore. } - override def onNeighborChange(world: IBlockAccess, pos: BlockPos, neighbor: BlockPos) = - world.getTileEntity(pos) match { + override def onNeighborChange(state: BlockState, world: IWorldReader, pos: BlockPos, neighbor: BlockPos) = + world.getBlockEntity(pos) match { case adapter: tileentity.Adapter => // TODO can we just pass the blockpos? val side = - if (neighbor == pos.down()) EnumFacing.DOWN - else if (neighbor == pos.up()) EnumFacing.UP - else if (neighbor == pos.north()) EnumFacing.NORTH - else if (neighbor == pos.south()) EnumFacing.SOUTH - else if (neighbor == pos.west()) EnumFacing.WEST - else if (neighbor == pos.east()) EnumFacing.EAST + if (neighbor == (pos.below():BlockPos)) Direction.DOWN + else if (neighbor == (pos.above():BlockPos)) Direction.UP + else if (neighbor == pos.north()) Direction.NORTH + else if (neighbor == pos.south()) Direction.SOUTH + else if (neighbor == pos.west()) Direction.WEST + else if (neighbor == pos.east()) Direction.EAST else throw new IllegalArgumentException("not a neighbor") // TODO wat adapter.neighborChanged(side) case _ => // Ignore. } - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { if (Wrench.holdsApplicableWrench(player, pos)) { - val sideToToggle = if (player.isSneaking) side.getOpposite else side - world.getTileEntity(pos) match { + val sideToToggle = if (player.isCrouching) side.getOpposite else side + world.getBlockEntity(pos) match { case adapter: tileentity.Adapter => - if (!world.isRemote) { + if (!world.isClientSide) { val oldValue = adapter.openSides(sideToToggle.ordinal()) adapter.setSideOpen(sideToToggle, !oldValue) } diff --git a/src/main/scala/li/cil/oc/common/block/Assembler.scala b/src/main/scala/li/cil/oc/common/block/Assembler.scala index f79f960e20..052b8b2da0 100644 --- a/src/main/scala/li/cil/oc/common/block/Assembler.scala +++ b/src/main/scala/li/cil/oc/common/block/Assembler.scala @@ -1,28 +1,35 @@ package li.cil.oc.common.block import li.cil.oc.Settings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.tileentity -import net.minecraft.block.state.IBlockState -import net.minecraft.util.EnumFacing +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Block +import net.minecraft.block.BlockState +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.math.shapes.VoxelShapes +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Assembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware with traits.GUI { - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def isFullCube(state: IBlockState): Boolean = false - - override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN || side == EnumFacing.UP - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN || side == EnumFacing.UP +class Assembler(props: Properties) extends SimpleBlock(props) with traits.PowerAcceptor with traits.StateAware with traits.GUI { + override def energyThroughput = Settings.get.assemblerRate - // ----------------------------------------------------------------------- // + val blockShape = { + val bottom = Block.box(0, 0, 0, 16, 7, 16) + val mid = Block.box(2, 7, 2, 14, 9, 14) + val top = Block.box(0, 9, 0, 16, 16, 16) + VoxelShapes.or(top, bottom, mid) + } - override def energyThroughput = Settings.get.assemblerRate + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = blockShape - override def guiType = GuiType.Assembler + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Assembler => ContainerTypes.openAssemblerGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Assembler() + override def newBlockEntity(world: IBlockReader) = new tileentity.Assembler(tileentity.TileEntityTypes.ASSEMBLER) } diff --git a/src/main/scala/li/cil/oc/common/block/Cable.scala b/src/main/scala/li/cil/oc/common/block/Cable.scala index cd6f2314d3..2431469a7f 100644 --- a/src/main/scala/li/cil/oc/common/block/Cable.scala +++ b/src/main/scala/li/cil/oc/common/block/Cable.scala @@ -2,27 +2,35 @@ package li.cil.oc.common.block import java.util -import li.cil.oc.common.block.property.UnlistedInteger +import li.cil.oc.common.block.property.PropertyCableConnection import li.cil.oc.common.capabilities.Capabilities import li.cil.oc.common.tileentity import li.cil.oc.util.Color +import li.cil.oc.util.ExtendedWorld._ +import li.cil.oc.util.ItemColorizer +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.{Entity, EntityLivingBase} -import net.minecraft.item.{EnumDyeColor, ItemStack} +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.{Entity, LivingEntity} +import net.minecraft.item.{BlockItemUseContext, DyeColor, ItemStack} +import net.minecraft.state.StateContainer import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.{AxisAlignedBB, BlockPos, RayTraceResult, Vec3d} -import net.minecraft.world.IBlockAccess +import net.minecraft.util.Direction +import net.minecraft.util.math.{BlockPos, RayTraceResult} +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.math.shapes.VoxelShapes +import net.minecraft.world.IBlockReader +import net.minecraft.world.IWorld import net.minecraft.world.World -import net.minecraftforge.common.property.ExtendedBlockState -import net.minecraftforge.common.property.IExtendedBlockState +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.common.extensions.IForgeBlock -import scala.collection.JavaConversions._ +import scala.collection.JavaConverters._ import scala.reflect.ClassTag -class Cable(protected implicit val tileTag: ClassTag[tileentity.Cable]) extends SimpleBlock with traits.CustomDrops[tileentity.Cable] { +class Cable(props: Properties) extends SimpleBlock(props) with IForgeBlock { // For Immibis Microblock support. val ImmibisMicroblocks_TransformableBlockMarker = null @@ -31,88 +39,71 @@ class Cable(protected implicit val tileTag: ClassTag[tileentity.Cable]) extends // ----------------------------------------------------------------------- // - override def createBlockState() = new ExtendedBlockState(this, Array.empty, Array(Cable.NeighborsProp,Cable.ColorProp, Cable.IsSideCableProp)) - - override def getExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos): IBlockState = - (state, world.getTileEntity(pos)) match { - case (extendedState: IExtendedBlockState, cable: tileentity.Cable) => - var isCableMask = 0 - for (side <- EnumFacing.values) { - if (world.getTileEntity(pos.offset(side)).isInstanceOf[tileentity.Cable]){ - isCableMask = Cable.mask(side, isCableMask) - } - } - extendedState.withProperty(Cable.NeighborsProp, Int.box(Cable.neighbors(world,pos))).withProperty(Cable.ColorProp, Int.box(cable.getColor)).withProperty(Cable.IsSideCableProp, Int.box(isCableMask)) - case _ => state - } - - // ----------------------------------------------------------------------- // - - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def isFullCube(state: IBlockState): Boolean = false - - override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = true - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false + override protected def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = { + builder.add(PropertyCableConnection.DOWN, PropertyCableConnection.UP, + PropertyCableConnection.NORTH, PropertyCableConnection.SOUTH, + PropertyCableConnection.WEST, PropertyCableConnection.EAST) + } - // ----------------------------------------------------------------------- // + registerDefaultState(defaultBlockState. + setValue(PropertyCableConnection.DOWN, PropertyCableConnection.Shape.NONE). + setValue(PropertyCableConnection.UP, PropertyCableConnection.Shape.NONE). + setValue(PropertyCableConnection.NORTH, PropertyCableConnection.Shape.NONE). + setValue(PropertyCableConnection.SOUTH, PropertyCableConnection.Shape.NONE). + setValue(PropertyCableConnection.WEST, PropertyCableConnection.Shape.NONE). + setValue(PropertyCableConnection.EAST, PropertyCableConnection.Shape.NONE)) + + override def getStateForPlacement(ctx: BlockItemUseContext): BlockState = { + val color = Cable.getConnectionColor(ctx.getItemInHand) + val fromPos = new BlockPos.Mutable() + Direction.values.foldLeft(defaultBlockState)((state, fromSide) => { + fromPos.setWithOffset(ctx.getClickedPos, fromSide) + val fromState = ctx.getLevel.getBlockState(fromPos) + Cable.updateState(state, null, color, fromSide, fromState, ctx.getLevel, fromPos) + }) + } - override def getPickBlock(state: IBlockState, target: RayTraceResult, world: World, pos: BlockPos, player: EntityPlayer) = - world.getTileEntity(pos) match { + override def getPickBlock(state: BlockState, target: RayTraceResult, world: IBlockReader, pos: BlockPos, player: PlayerEntity) = + world.getBlockEntity(pos) match { case t: tileentity.Cable => t.createItemStack() case _ => createItemStack() } - override def getBoundingBox(state: IBlockState, world: IBlockAccess, pos: BlockPos): AxisAlignedBB = Cable.bounds(world, pos) - - override def addCollisionBoxToList(state: IBlockState, worldIn: World, pos: BlockPos, entityBox: AxisAlignedBB, collidingBoxes: util.List[AxisAlignedBB], entityIn: Entity, isActualState: Boolean): Unit = { - Cable.parts(worldIn, pos, entityBox, collidingBoxes) - } - - override def collisionRayTrace(state: IBlockState, world: World, pos: BlockPos, start: Vec3d, end: Vec3d): RayTraceResult = { - var distance = Double.PositiveInfinity - var result: RayTraceResult = null - - val boxes = new util.ArrayList[AxisAlignedBB] - Cable.parts(world, pos, Block.FULL_BLOCK_AABB.offset(pos), boxes) - for (part: AxisAlignedBB <- boxes) { - val hit = part.calculateIntercept(start, end) - if (hit != null) { - val hitDistance = hit.hitVec.squareDistanceTo(start) - if (hitDistance < distance) { - distance = hitDistance; - result = hit; - } + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = Cable.shape(state) + + override def neighborChanged(state: BlockState, world: World, pos: BlockPos, other: Block, otherPos: BlockPos, moved: Boolean): Unit = { + if (world.isClientSide) return + val newState = world.getBlockEntity(pos) match { + case t: tileentity.Cable => { + val fromPos = new BlockPos.Mutable() + Direction.values.foldLeft(state)((state, fromSide) => { + fromPos.setWithOffset(pos, fromSide) + val fromState = world.getBlockState(fromPos) + Cable.updateState(state, t, -1, fromSide, fromState, world, fromPos) + }) } + case _ => state } - - if (result == null) null - else new RayTraceResult(result.hitVec, result.sideHit, pos) + if (newState != state) world.setBlock(pos, newState, 0x13) } - // ----------------------------------------------------------------------- // - - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Cable() + override def updateShape(state: BlockState, fromSide: Direction, fromState: BlockState, world: IWorld, pos: BlockPos, fromPos: BlockPos): BlockState = + Cable.updateState(state, world.getBlockEntity(pos), -1, fromSide, fromState, world, fromPos) // ----------------------------------------------------------------------- // - override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, neighborBlock: Block, sourcePos: BlockPos) { - world.notifyBlockUpdate(pos, state, state, 3) - super.neighborChanged(state, world, pos, neighborBlock, sourcePos) - } + override def newBlockEntity(world: IBlockReader) = new tileentity.Cable(tileentity.TileEntityTypes.CABLE) - override protected def doCustomInit(tileEntity: tileentity.Cable, player: EntityLivingBase, stack: ItemStack): Unit = { - super.doCustomInit(tileEntity, player, stack) - if (!tileEntity.world.isRemote) { - tileEntity.fromItemStack(stack) - } - } + // ----------------------------------------------------------------------- // - override protected def doCustomDrops(tileEntity: tileentity.Cable, player: EntityPlayer, willHarvest: Boolean): Unit = { - super.doCustomDrops(tileEntity, player, willHarvest) - if (!player.capabilities.isCreativeMode) { - Block.spawnAsEntity(tileEntity.world, tileEntity.getPos, tileEntity.createItemStack()) + override def setPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity, stack: ItemStack): Unit = { + super.setPlacedBy(world, pos, state, placer, stack) + world.getBlockEntity(pos) match { + case tileEntity: tileentity.Cable => { + tileEntity.fromItemStack(stack) + state.updateNeighbourShapes(world, pos, 2) + } + case _ => } } } @@ -121,108 +112,100 @@ object Cable { final val MIN = 0.375 final val MAX = 1 - MIN - final val DefaultBounds: AxisAlignedBB = new AxisAlignedBB(MIN, MIN, MIN, MAX, MAX, MAX) + final val DefaultShape: VoxelShape = VoxelShapes.box(MIN, MIN, MIN, MAX, MAX, MAX) - final val CachedParts: Array[AxisAlignedBB] = Array( - new AxisAlignedBB( MIN, 0, MIN, MAX, MIN, MAX ), // Down - new AxisAlignedBB( MIN, MAX, MIN, MAX, 1, MAX ), // Up - new AxisAlignedBB( MIN, MIN, 0, MAX, MAX, MIN ), // North - new AxisAlignedBB( MIN, MIN, MAX, MAX, MAX, 1 ), // South - new AxisAlignedBB( 0, MIN, MIN, MIN, MAX, MAX ), // West - new AxisAlignedBB( MAX, MIN, MIN, 1, MAX, MAX )) // East + final val CachedParts: Array[VoxelShape] = Array( + VoxelShapes.box( MIN, 0, MIN, MAX, MIN, MAX ), // Down + VoxelShapes.box( MIN, MAX, MIN, MAX, 1, MAX ), // Up + VoxelShapes.box( MIN, MIN, 0, MAX, MAX, MIN ), // North + VoxelShapes.box( MIN, MIN, MAX, MAX, MAX, 1 ), // South + VoxelShapes.box( 0, MIN, MIN, MIN, MAX, MAX ), // West + VoxelShapes.box( MAX, MIN, MIN, 1, MAX, MAX )) // East final val CachedBounds = { // 6 directions = 6 bits = 11111111b >> 2 = 0xFF >> 2 (0 to 0xFF >> 2).map(mask => { - EnumFacing.VALUES.foldLeft(DefaultBounds)((bound, side) => { - if (((1 << side.getIndex) & mask) != 0) bound.union(CachedParts(side.ordinal())) - else bound + Direction.values.foldLeft(DefaultShape)((shape, side) => { + if (((1 << side.get3DDataValue) & mask) != 0) VoxelShapes.or(shape, CachedParts(side.ordinal())) + else shape }) }).toArray } - final val NeighborsProp = new UnlistedInteger("neighbors") - final val ColorProp = new UnlistedInteger("color") - final val IsSideCableProp = new UnlistedInteger("is_cable") + def mask(side: Direction, value: Int = 0) = value | (1 << side.get3DDataValue) - def mask(side: EnumFacing, value: Int = 0) = value | (1 << side.getIndex) - - def neighbors(world: IBlockAccess, pos: BlockPos) = { + def shape(state: BlockState): VoxelShape = { var result = 0 - val tileEntity = world.getTileEntity(pos) - for (side <- EnumFacing.values) { - val tpos = pos.offset(side) - val hasNode = hasNetworkNode(tileEntity, side) - if (hasNode && (world match { - case world: World => world.isBlockLoaded(tpos) - case _ => !world.isAirBlock(tpos) - })) { - val neighborTileEntity = world.getTileEntity(tpos) - if (neighborTileEntity != null && neighborTileEntity.getWorld != null) { - val neighborHasNode = hasNetworkNode(neighborTileEntity, side.getOpposite) - val canConnectColor = canConnectBasedOnColor(tileEntity, neighborTileEntity) - val canConnectIM = canConnectFromSideIM(tileEntity, side) && canConnectFromSideIM(neighborTileEntity, side.getOpposite) - if (neighborHasNode && canConnectColor && canConnectIM) { - result = mask(side, result) - } - } + for (side <- Direction.values) { + val sideShape = state.getValue(PropertyCableConnection.BY_DIRECTION.get(side)) + if (sideShape != PropertyCableConnection.Shape.NONE) { + result = mask(side, result) } } - result + Cable.CachedBounds(result) } - def bounds(world: IBlockAccess, pos: BlockPos) = Cable.CachedBounds(Cable.neighbors(world, pos)) - - def parts(world: IBlockAccess, pos: BlockPos, entityBox : AxisAlignedBB, boxes : util.List[AxisAlignedBB]) = { - val center = Cable.DefaultBounds.offset(pos) - if (entityBox.intersects(center)) boxes.add(center) - - val mask = Cable.neighbors(world, pos) - for (side <- EnumFacing.VALUES) { - if(((1 << side.getIndex) & mask) != 0) { - val part = Cable.CachedParts(side.ordinal()).offset(pos) - if (entityBox.intersects(part)) boxes.add(part) + def updateState(state: BlockState, tileEntity: TileEntity, defaultColor: Int, fromSide: Direction, fromState: BlockState, world: IBlockReader, fromPos: BlockPos): BlockState = { + val prop = PropertyCableConnection.BY_DIRECTION.get(fromSide) + val neighborTileEntity = world.getBlockEntity(fromPos) + if (neighborTileEntity != null && neighborTileEntity.getLevel != null) { + val neighborHasNode = hasNetworkNode(neighborTileEntity, fromSide.getOpposite) + val canConnectColor = canConnectBasedOnColor(tileEntity, neighborTileEntity, defaultColor) + val canConnectIM = canConnectFromSideIM(tileEntity, fromSide) && canConnectFromSideIM(neighborTileEntity, fromSide.getOpposite) + if (neighborHasNode && canConnectColor && canConnectIM) { + if (fromState.is(state.getBlock)) { + return state.setValue(prop, PropertyCableConnection.Shape.CABLE) + } + else { + return state.setValue(prop, PropertyCableConnection.Shape.DEVICE) + } } } + state.setValue(prop, PropertyCableConnection.Shape.NONE) } - private def hasNetworkNode(tileEntity: TileEntity, side: EnumFacing): Boolean = { + private def hasNetworkNode(tileEntity: TileEntity, side: Direction): Boolean = { if (tileEntity != null) { if (tileEntity.isInstanceOf[tileentity.RobotProxy]) return false - if (tileEntity.hasCapability(Capabilities.SidedEnvironmentCapability, side)) { - val host = tileEntity.getCapability(Capabilities.SidedEnvironmentCapability, side) + if (tileEntity.getCapability(Capabilities.SidedEnvironmentCapability, side).isPresent) { + val host = tileEntity.getCapability(Capabilities.SidedEnvironmentCapability, side).orElse(null) if (host != null) { - return if (tileEntity.getWorld.isRemote) host.canConnect(side) else host.sidedNode(side) != null + return if (tileEntity.getLevel.isClientSide) host.canConnect(side) else host.sidedNode(side) != null } } - if (tileEntity.hasCapability(Capabilities.EnvironmentCapability, side)) { + if (tileEntity.getCapability(Capabilities.EnvironmentCapability, side).isPresent) { val host = tileEntity.getCapability(Capabilities.EnvironmentCapability, side) - if (host != null) return true + if (host.isPresent) return true } } false } + private def getConnectionColor(stack: ItemStack): Int = { + val color = ItemColorizer.getColor(stack) + if (color == -1) Color.rgbValues(DyeColor.LIGHT_GRAY) else color + } + private def getConnectionColor(tileEntity: TileEntity): Int = { if (tileEntity != null) { - if (tileEntity.hasCapability(Capabilities.ColoredCapability, null)) { - val colored = tileEntity.getCapability(Capabilities.ColoredCapability, null) + if (tileEntity.getCapability(Capabilities.ColoredCapability, null).isPresent) { + val colored = tileEntity.getCapability(Capabilities.ColoredCapability, null).orElse(null) if (colored != null && colored.controlsConnectivity) return colored.getColor } } - Color.rgbValues(EnumDyeColor.SILVER) + Color.rgbValues(DyeColor.LIGHT_GRAY) } - private def canConnectBasedOnColor(te1: TileEntity, te2: TileEntity) = { - val (c1, c2) = (getConnectionColor(te1), getConnectionColor(te2)) - c1 == c2 || c1 == Color.rgbValues(EnumDyeColor.SILVER) || c2 == Color.rgbValues(EnumDyeColor.SILVER) + private def canConnectBasedOnColor(te1: TileEntity, te2: TileEntity, c1Default: Int = Color.rgbValues(DyeColor.LIGHT_GRAY)) = { + val (c1, c2) = (if (te1 == null) c1Default else getConnectionColor(te1), getConnectionColor(te2)) + c1 == c2 || c1 == Color.rgbValues(DyeColor.LIGHT_GRAY) || c2 == Color.rgbValues(DyeColor.LIGHT_GRAY) } - private def canConnectFromSideIM(tileEntity: TileEntity, side: EnumFacing) = + private def canConnectFromSideIM(tileEntity: TileEntity, side: Direction) = tileEntity match { case im: tileentity.traits.ImmibisMicroblock => im.ImmibisMicroblocks_isSideOpen(side.ordinal) case _ => true diff --git a/src/main/scala/li/cil/oc/common/block/Capacitor.scala b/src/main/scala/li/cil/oc/common/block/Capacitor.scala index 54fb043f3a..1d792ef4a0 100644 --- a/src/main/scala/li/cil/oc/common/block/Capacitor.scala +++ b/src/main/scala/li/cil/oc/common/block/Capacitor.scala @@ -3,37 +3,40 @@ package li.cil.oc.common.block import java.util.Random import li.cil.oc.common.tileentity +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.util.math.BlockPos +import net.minecraft.world.IBlockReader import net.minecraft.world.World +import net.minecraft.world.server.ServerWorld -class Capacitor extends SimpleBlock { - setTickRandomly(true) +class Capacitor(props: Properties) extends SimpleBlock(props) { + @Deprecated + override def isRandomlyTicking(state: BlockState) = true // ----------------------------------------------------------------------- // - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Capacitor() + override def newBlockEntity(world: IBlockReader) = new tileentity.Capacitor(tileentity.TileEntityTypes.CAPACITOR) // ----------------------------------------------------------------------- // - override def hasComparatorInputOverride(state: IBlockState): Boolean = true + override def hasAnalogOutputSignal(state: BlockState): Boolean = true - override def getComparatorInputOverride(state: IBlockState, world: World, pos: BlockPos): Int = - world.getTileEntity(pos) match { - case capacitor: tileentity.Capacitor if !world.isRemote => + override def getAnalogOutputSignal(state: BlockState, world: World, pos: BlockPos): Int = + world.getBlockEntity(pos) match { + case capacitor: tileentity.Capacitor if !world.isClientSide => math.round(15 * capacitor.node.localBuffer / capacitor.node.localBufferSize).toInt case _ => 0 } - override def updateTick(world: World, pos: BlockPos, state: IBlockState, rand: Random): Unit = { - world.notifyNeighborsOfStateChange(pos, this, false) + override def tick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random): Unit = { + world.updateNeighborsAt(pos, this) } - override def tickRate(world: World) = 1 - - override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit = - world.getTileEntity(pos) match { + @Deprecated + override def neighborChanged(state: BlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos, b: Boolean): Unit = + world.getBlockEntity(pos) match { case capacitor: tileentity.Capacitor => capacitor.recomputeCapacity() case _ => } diff --git a/src/main/scala/li/cil/oc/common/block/CarpetedCapacitor.scala b/src/main/scala/li/cil/oc/common/block/CarpetedCapacitor.scala index 03108dce6d..14606b4034 100644 --- a/src/main/scala/li/cil/oc/common/block/CarpetedCapacitor.scala +++ b/src/main/scala/li/cil/oc/common/block/CarpetedCapacitor.scala @@ -1,8 +1,9 @@ package li.cil.oc.common.block import li.cil.oc.common.tileentity -import net.minecraft.world.World +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.world.IBlockReader -class CarpetedCapacitor extends Capacitor { - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.CarpetedCapacitor() +class CarpetedCapacitor(props: Properties) extends Capacitor(props) { + override def newBlockEntity(world: IBlockReader) = new tileentity.CarpetedCapacitor(tileentity.TileEntityTypes.CARPETED_CAPACITOR) } diff --git a/src/main/scala/li/cil/oc/common/block/Case.scala b/src/main/scala/li/cil/oc/common/block/Case.scala index 08cf662b55..58ab6f67db 100644 --- a/src/main/scala/li/cil/oc/common/block/Case.scala +++ b/src/main/scala/li/cil/oc/common/block/Case.scala @@ -3,34 +3,39 @@ package li.cil.oc.common.block import java.util import li.cil.oc.Settings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.common.tileentity -import li.cil.oc.util.Rarity import li.cil.oc.util.Tooltip -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Block +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.fluid.FluidState import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.state.StateContainer +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor with traits.StateAware with traits.GUI { - override def createBlockState() = new BlockStateContainer(this, PropertyRotatable.Facing, property.PropertyRunning.Running) +import scala.collection.convert.ImplicitConversionsToScala._ - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Facing, EnumFacing.getHorizontal(meta >> 1)) - - override def getMetaFromState(state: IBlockState): Int = state.getValue(PropertyRotatable.Facing).getHorizontalIndex << 1 | (if (state.getValue(property.PropertyRunning.Running)) 1 else 0) +class Case(props: Properties, val tier: Int) extends RedstoneAware(props) with traits.PowerAcceptor with traits.StateAware with traits.GUI { + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Facing, property.PropertyRunning.Running) // ----------------------------------------------------------------------- // - override def rarity(stack: ItemStack) = Rarity.byTier(tier) - - override protected def tooltipBody(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - tooltip.addAll(Tooltip.get(getClass.getSimpleName.toLowerCase, slots)) + override protected def tooltipBody(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + for (curr <- Tooltip.get(getClass.getSimpleName.toLowerCase, slots)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } private def slots = tier match { @@ -44,16 +49,19 @@ class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor with t override def energyThroughput = Settings.get.caseRate(tier) - override def guiType = GuiType.Case + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Case if te.stillValid(player) => ContainerTypes.openCaseGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Case(tier) + override def newBlockEntity(world: IBlockReader) = new tileentity.Case(tileentity.TileEntityTypes.CASE, tier) // ----------------------------------------------------------------------- // - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = { - if (player.isSneaking) { - if (!world.isRemote) world.getTileEntity(pos) match { - case computer: tileentity.Case if !computer.machine.isRunning && computer.isUsableByPlayer(player) => computer.machine.start() + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = { + if (player.isCrouching) { + if (!world.isClientSide) world.getBlockEntity(pos) match { + case computer: tileentity.Case if !computer.machine.isRunning && computer.stillValid(player) => computer.machine.start() case _ => } true @@ -61,11 +69,11 @@ class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor with t else super.localOnBlockActivated(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ) } - override def removedByPlayer(state: IBlockState, world: World, pos: BlockPos, player: EntityPlayer, willHarvest: Boolean): Boolean = - world.getTileEntity(pos) match { + override def removedByPlayer(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, willHarvest: Boolean, fluid: FluidState): Boolean = + world.getBlockEntity(pos) match { case c: tileentity.Case => - if (c.isCreative && (!player.capabilities.isCreativeMode || !c.canInteract(player.getName))) false - else c.canInteract(player.getName) && super.removedByPlayer(state, world, pos, player, willHarvest) - case _ => super.removedByPlayer(state, world, pos, player, willHarvest) + if (c.isCreative && (!player.isCreative || !c.canInteract(player.getName.getString))) false + else c.canInteract(player.getName.getString) && super.removedByPlayer(state, world, pos, player, willHarvest, fluid) + case _ => super.removedByPlayer(state, world, pos, player, willHarvest, fluid) } } diff --git a/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala b/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala index dbbe315f88..4dc38c6d90 100644 --- a/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala +++ b/src/main/scala/li/cil/oc/common/block/ChameliumBlock.scala @@ -1,27 +1,42 @@ package li.cil.oc.common.block -import net.minecraft.block.material.Material -import net.minecraft.block.properties.PropertyEnum -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState -import net.minecraft.item.EnumDyeColor +import java.util.List + +import net.minecraft.block.Block +import net.minecraft.block.BlockState +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.item.BlockItemUseContext +import net.minecraft.item.DyeColor +import net.minecraft.item.ItemGroup +import net.minecraft.item.ItemStack +import net.minecraft.state.EnumProperty +import net.minecraft.state.StateContainer +import net.minecraft.util.NonNullList +import net.minecraft.util.math.BlockPos +import net.minecraft.world.IBlockReader object ChameliumBlock { - final val Color = PropertyEnum.create("color", classOf[EnumDyeColor]) + final val Color = EnumProperty.create("color", classOf[DyeColor]) } -class ChameliumBlock extends SimpleBlock(Material.ROCK) { - setDefaultState(blockState.getBaseState.withProperty(ChameliumBlock.Color, EnumDyeColor.BLACK)) - - override def damageDropped(state: IBlockState): Int = getMetaFromState(state) - - override def getStateFromMeta(meta: Int): IBlockState = - getDefaultState.withProperty(ChameliumBlock.Color, EnumDyeColor.byDyeDamage(meta)) - - override def getMetaFromState(state: IBlockState): Int = - state.getValue(ChameliumBlock.Color).getDyeDamage - - override def createBlockState() = new BlockStateContainer(this, ChameliumBlock.Color) - - override def hasTileEntity(state: IBlockState): Boolean = false +class ChameliumBlock(props: Properties) extends SimpleBlock(props) { + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]): Unit = { + builder.add(ChameliumBlock.Color) + } + registerDefaultState(stateDefinition.any.setValue(ChameliumBlock.Color, DyeColor.BLACK)) + + override def getCloneItemStack(world: IBlockReader, pos: BlockPos, state: BlockState): ItemStack = { + val stack = new ItemStack(this) + stack.setDamageValue(state.getValue(ChameliumBlock.Color).getId) + stack + } + + override def getStateForPlacement(ctx: BlockItemUseContext): BlockState = + defaultBlockState.setValue(ChameliumBlock.Color, DyeColor.byId(ctx.getItemInHand.getDamageValue)) + + override def fillItemCategory(tab: ItemGroup, list: NonNullList[ItemStack]) { + val stack = new ItemStack(this, 1) + stack.setDamageValue(defaultBlockState.getValue(ChameliumBlock.Color).getId) + list.add(stack) + } } diff --git a/src/main/scala/li/cil/oc/common/block/Charger.scala b/src/main/scala/li/cil/oc/common/block/Charger.scala index 70e953d019..985a6000ba 100644 --- a/src/main/scala/li/cil/oc/common/block/Charger.scala +++ b/src/main/scala/li/cil/oc/common/block/Charger.scala @@ -1,47 +1,49 @@ package li.cil.oc.common.block import li.cil.oc.Settings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.common.tileentity import li.cil.oc.integration.util.Wrench import li.cil.oc.server.PacketSender +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.state.StateContainer +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Charger extends RedstoneAware with traits.PowerAcceptor with traits.StateAware with traits.GUI { - override def createBlockState() = new BlockStateContainer(this, PropertyRotatable.Facing) - - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Facing, EnumFacing.getHorizontal(meta)) - - override def getMetaFromState(state: IBlockState): Int = state.getValue(PropertyRotatable.Facing).getHorizontalIndex +class Charger(props: Properties) extends RedstoneAware(props) with traits.PowerAcceptor with traits.StateAware with traits.GUI { + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Facing) // ----------------------------------------------------------------------- // override def energyThroughput = Settings.get.chargerRate - override def guiType = GuiType.Charger + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Charger => ContainerTypes.openChargerGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Charger() + override def newBlockEntity(world: IBlockReader) = new tileentity.Charger(tileentity.TileEntityTypes.CHARGER) // ----------------------------------------------------------------------- // - override def canConnectRedstone(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = true + override def canConnectRedstone(state: BlockState, world: IBlockReader, pos: BlockPos, side: Direction): Boolean = true // ----------------------------------------------------------------------- // - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = - if (Wrench.holdsApplicableWrench(player, pos)) world.getTileEntity(pos) match { + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = + if (Wrench.holdsApplicableWrench(player, pos)) world.getBlockEntity(pos) match { case charger: tileentity.Charger => - if (!world.isRemote) { + if (!world.isClientSide) { charger.invertSignal = !charger.invertSignal charger.chargeSpeed = 1.0 - charger.chargeSpeed PacketSender.sendChargerState(charger) @@ -52,11 +54,12 @@ class Charger extends RedstoneAware with traits.PowerAcceptor with traits.StateA } else super.localOnBlockActivated(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ) - override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit = { - world.getTileEntity(pos) match { + @Deprecated + override def neighborChanged(state: BlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos, b: Boolean): Unit = { + world.getBlockEntity(pos) match { case charger: tileentity.Charger => charger.onNeighborChanged() case _ => } - super.neighborChanged(state, world, pos, block, fromPos) + super.neighborChanged(state, world, pos, block, fromPos, b) } } diff --git a/src/main/scala/li/cil/oc/common/block/Disassembler.scala b/src/main/scala/li/cil/oc/common/block/Disassembler.scala index d938805201..058cc5bbea 100644 --- a/src/main/scala/li/cil/oc/common/block/Disassembler.scala +++ b/src/main/scala/li/cil/oc/common/block/Disassembler.scala @@ -3,25 +3,38 @@ package li.cil.oc.common.block import java.util import li.cil.oc.Settings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.tileentity import li.cil.oc.util.Tooltip -import net.minecraft.block.state.IBlockState +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Disassembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware with traits.GUI { - override protected def tooltipBody(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - tooltip.addAll(Tooltip.get(getClass.getSimpleName.toLowerCase, (Settings.get.disassemblerBreakChance * 100).toInt.toString)) +import scala.collection.convert.ImplicitConversionsToScala._ + +class Disassembler(props: Properties) extends SimpleBlock(props) with traits.PowerAcceptor with traits.StateAware with traits.GUI { + override protected def tooltipBody(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + for (curr <- Tooltip.get(getClass.getSimpleName.toLowerCase, (Settings.get.disassemblerBreakChance * 100).toInt.toString)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } // ----------------------------------------------------------------------- // override def energyThroughput = Settings.get.disassemblerRate - override def guiType = GuiType.Disassembler + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Disassembler => ContainerTypes.openDisassemblerGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Disassembler() + override def newBlockEntity(world: IBlockReader) = new tileentity.Disassembler(tileentity.TileEntityTypes.DISASSEMBLER) } diff --git a/src/main/scala/li/cil/oc/common/block/DiskDrive.scala b/src/main/scala/li/cil/oc/common/block/DiskDrive.scala index 3c4e1ef5b4..e42d5fb0e2 100644 --- a/src/main/scala/li/cil/oc/common/block/DiskDrive.scala +++ b/src/main/scala/li/cil/oc/common/block/DiskDrive.scala @@ -2,73 +2,77 @@ package li.cil.oc.common.block import java.util -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.common.tileentity import li.cil.oc.integration.Mods import li.cil.oc.util.Tooltip -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Block +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.state.StateContainer +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class DiskDrive extends SimpleBlock with traits.GUI { - override def createBlockState() = new BlockStateContainer(this, PropertyRotatable.Facing) +import scala.collection.convert.ImplicitConversionsToScala._ - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Facing, EnumFacing.getHorizontal(meta)) - - override def getMetaFromState(state: IBlockState): Int = state.getValue(PropertyRotatable.Facing).getHorizontalIndex +class DiskDrive(props: Properties) extends SimpleBlock(props) with traits.GUI { + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Facing) // ----------------------------------------------------------------------- // - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - super.tooltipTail(metadata, stack, world, tooltip, flag) + override protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.tooltipTail(stack, world, tooltip, flag) if (Mods.ComputerCraft.isModAvailable) { - tooltip.addAll(Tooltip.get(getClass.getSimpleName + ".CC")) + for (curr <- Tooltip.get(getClass.getSimpleName + ".CC")) tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) } } // ----------------------------------------------------------------------- // - override def guiType = GuiType.DiskDrive + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.DiskDrive => ContainerTypes.openDiskDriveGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.DiskDrive() + override def newBlockEntity(world: IBlockReader) = new tileentity.DiskDrive(tileentity.TileEntityTypes.DISK_DRIVE) // ----------------------------------------------------------------------- // - override def hasComparatorInputOverride(state: IBlockState): Boolean = true + override def hasAnalogOutputSignal(state: BlockState): Boolean = true - override def getComparatorInputOverride(state: IBlockState, world: World, pos: BlockPos): Int = - world.getTileEntity(pos) match { - case drive: tileentity.DiskDrive if !drive.getStackInSlot(0).isEmpty => 15 + override def getAnalogOutputSignal(state: BlockState, world: World, pos: BlockPos): Int = + world.getBlockEntity(pos) match { + case drive: tileentity.DiskDrive if !drive.getItem(0).isEmpty => 15 case _ => 0 } // ----------------------------------------------------------------------- // - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { // Behavior: sneaking -> Insert[+Eject], not sneaking -> GUI. - if (player.isSneaking) world.getTileEntity(pos) match { + if (player.isCrouching) world.getBlockEntity(pos) match { case drive: tileentity.DiskDrive => - val isDiskInDrive = drive.getStackInSlot(0) != null - val isHoldingDisk = drive.isItemValidForSlot(0, heldItem) + val isDiskInDrive = drive.getItem(0) != null + val isHoldingDisk = drive.canPlaceItem(0, heldItem) if (isDiskInDrive) { - if (!world.isRemote) { + if (!world.isClientSide) { drive.dropSlot(0, 1, Option(drive.facing)) } } if (isHoldingDisk) { // Insert the disk. - drive.setInventorySlotContents(0, heldItem.copy().splitStack(1)) - if (hand == EnumHand.MAIN_HAND) - player.inventory.decrStackSize(player.inventory.currentItem, 1) - else - player.inventory.offHandInventory.get(0).shrink(1) + drive.setItem(0, heldItem.split(1)) } isDiskInDrive || isHoldingDisk case _ => false diff --git a/src/main/scala/li/cil/oc/common/block/FakeEndstone.scala b/src/main/scala/li/cil/oc/common/block/FakeEndstone.scala index 97297061f8..e6f17bc1ae 100644 --- a/src/main/scala/li/cil/oc/common/block/FakeEndstone.scala +++ b/src/main/scala/li/cil/oc/common/block/FakeEndstone.scala @@ -1,11 +1,8 @@ package li.cil.oc.common.block +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState import net.minecraft.block.material.Material -import net.minecraft.block.state.IBlockState -class FakeEndstone extends SimpleBlock(Material.ROCK) { - setHardness(3) - setResistance(15) - - override def hasTileEntity(state: IBlockState): Boolean = false +class FakeEndstone(props: Properties) extends SimpleBlock(props) { } diff --git a/src/main/scala/li/cil/oc/common/block/Geolyzer.scala b/src/main/scala/li/cil/oc/common/block/Geolyzer.scala index 0f87c555d7..7a3d059b35 100644 --- a/src/main/scala/li/cil/oc/common/block/Geolyzer.scala +++ b/src/main/scala/li/cil/oc/common/block/Geolyzer.scala @@ -1,8 +1,10 @@ package li.cil.oc.common.block import li.cil.oc.common.tileentity +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Geolyzer extends SimpleBlock { - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Geolyzer() +class Geolyzer(props: Properties) extends SimpleBlock(props) { + override def newBlockEntity(world: IBlockReader) = new tileentity.Geolyzer(tileentity.TileEntityTypes.GEOLYZER) } diff --git a/src/main/scala/li/cil/oc/common/block/Hologram.scala b/src/main/scala/li/cil/oc/common/block/Hologram.scala index 05ad5ad18a..1dae9a89ec 100644 --- a/src/main/scala/li/cil/oc/common/block/Hologram.scala +++ b/src/main/scala/li/cil/oc/common/block/Hologram.scala @@ -5,47 +5,39 @@ import java.util import li.cil.oc.common.tileentity import li.cil.oc.util.Rarity import li.cil.oc.util.Tooltip -import net.minecraft.block.state.IBlockState +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.AxisAlignedBB import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess -import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.math.shapes.VoxelShapes +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -class Hologram(val tier: Int) extends SimpleBlock { - val bounds = new AxisAlignedBB(0, 0, 0, 1, 0.5f, 1) +import scala.collection.convert.ImplicitConversionsToScala._ - // ----------------------------------------------------------------------- // - - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def isFullCube(state: IBlockState): Boolean = false - - override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN +class Hologram(props: Properties, val tier: Int) extends SimpleBlock(props) { + val shape = VoxelShapes.box(0, 0, 0, 1, 0.5, 1) - @SideOnly(Side.CLIENT) - override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = { - super.shouldSideBeRendered(state, world, pos, side) || side == EnumFacing.UP - } - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN + // ----------------------------------------------------------------------- // - override def getBoundingBox(state: IBlockState, world: IBlockAccess, pos: BlockPos): AxisAlignedBB = bounds + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = shape // ----------------------------------------------------------------------- // - override def rarity(stack: ItemStack) = Rarity.byTier(tier) - - override protected def tooltipBody(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - tooltip.addAll(Tooltip.get(getClass.getSimpleName.toLowerCase() + tier)) + override protected def tooltipBody(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + for (curr <- Tooltip.get(getClass.getSimpleName.toLowerCase() + tier)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } // ----------------------------------------------------------------------- // - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Hologram(tier) + override def newBlockEntity(world: IBlockReader) = new tileentity.Hologram(tileentity.TileEntityTypes.HOLOGRAM, tier) } diff --git a/src/main/scala/li/cil/oc/common/block/Item.scala b/src/main/scala/li/cil/oc/common/block/Item.scala index 929196193d..6f11d82e38 100644 --- a/src/main/scala/li/cil/oc/common/block/Item.scala +++ b/src/main/scala/li/cil/oc/common/block/Item.scala @@ -5,52 +5,51 @@ import java.util import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.api +import li.cil.oc.common.block +import li.cil.oc.common.item.data.MicrocontrollerData import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.tileentity import li.cil.oc.util.Color import li.cil.oc.util.ItemColorizer +import li.cil.oc.util.Rarity import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState -import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumDyeColor -import net.minecraft.item.EnumRarity -import net.minecraft.item.ItemBlock +import net.minecraft.block.BlockState +import net.minecraft.item // Rarity +import net.minecraft.item.BlockItem +import net.minecraft.item.BlockItemUseContext +import net.minecraft.item.DyeColor +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.BlockPos -import net.minecraft.world.World +import net.minecraft.util.Direction +import net.minecraft.util.math.BlockRayTraceResult +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent -class Item(value: Block) extends ItemBlock(value) { - setHasSubtypes(true) - - override def addInformation(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - super.addInformation(stack, world, tooltip, flag) - block match { - case (simple: SimpleBlock) => - simple.addInformation(getMetadata(stack.getItemDamage), stack, world, tooltip, flag) - case _ => +class Item(value: Block, props: Properties) extends BlockItem(value, props) { + override def getRarity(stack: ItemStack): item.Rarity = getBlock match { + case _: block.Microcontroller => { + val data = new MicrocontrollerData(stack) + Rarity.byTier(data.tier) } + case _: block.RobotProxy => { + val data = new RobotData(stack) + Rarity.byTier(data.tier) + } + case _ => super.getRarity(stack) } - override def getRarity(stack: ItemStack): EnumRarity = block match { - case simple: SimpleBlock => simple.rarity(stack) - case _ => EnumRarity.COMMON - } - - override def getMetadata(itemDamage: Int): Int = itemDamage - - override def getItemStackDisplayName(stack: ItemStack): String = { + override def getName(stack: ItemStack): ITextComponent = { if (api.Items.get(stack) == api.Items.get(Constants.BlockName.Print)) { val data = new PrintData(stack) - data.label.getOrElse(super.getItemStackDisplayName(stack)) + data.label.map(new StringTextComponent(_)).getOrElse(super.getName(stack)) } - else super.getItemStackDisplayName(stack) + else super.getName(stack) } - override def getUnlocalizedName: String = block match { - case simple: SimpleBlock => simple.getUnlocalizedName + @Deprecated + override def getDescriptionId: String = getBlock match { + case simple: SimpleBlock => simple.getDescriptionId case _ => Settings.namespace + "tile" } @@ -59,14 +58,14 @@ class Item(value: Block) extends ItemBlock(value) { if (ItemColorizer.hasColor(stack)) { ItemColorizer.getColor(stack) } - else Color.rgbValues(EnumDyeColor.SILVER) + else Color.rgbValues(DyeColor.LIGHT_GRAY) } else super.getDamage(stack) } override def setDamage(stack: ItemStack, damage: Int): Unit = { if (api.Items.get(stack) == api.Items.get(Constants.BlockName.Cable)) { - if(damage != Color.rgbValues(EnumDyeColor.SILVER)) { + if(damage != Color.rgbValues(DyeColor.LIGHT_GRAY)) { ItemColorizer.setColor(stack, damage) } else { ItemColorizer.removeColor(stack) @@ -75,24 +74,25 @@ class Item(value: Block) extends ItemBlock(value) { else super.setDamage(stack, damage) } - override def isBookEnchantable(a: ItemStack, b: ItemStack) = false - - override def placeBlockAt(stack: ItemStack, player: EntityPlayer, world: World, pos: BlockPos, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float, newState: IBlockState): Boolean = { + override def placeBlock(ctx: BlockItemUseContext, newState: BlockState): Boolean = { // When placing robots in creative mode, we have to copy the stack // manually before it's placed to ensure different component addresses // in the different robots, to avoid interference of screens e.g. - val needsCopying = player.capabilities.isCreativeMode && api.Items.get(stack) == api.Items.get(Constants.BlockName.Robot) - val stackToUse = if (needsCopying) new RobotData(stack).copyItemStack() else stack - if (super.placeBlockAt(stackToUse, player, world, pos, side, hitX, hitY, hitZ, newState)) { + val needsCopying = ctx.getPlayer.isCreative && api.Items.get(ctx.getItemInHand) == api.Items.get(Constants.BlockName.Robot) + val ctxToUse = if (needsCopying) { + val stackToUse = new RobotData(ctx.getItemInHand).copyItemStack() + val hitResult = new BlockRayTraceResult(ctx.getClickLocation, ctx.getClickedFace, ctx.getClickedPos, ctx.isInside) + new BlockItemUseContext(ctx.getLevel, ctx.getPlayer, ctx.getHand, stackToUse, hitResult) + } + else ctx + if (super.placeBlock(ctxToUse, newState)) { // If it's a rotatable block try to make it face the player. - world.getTileEntity(pos) match { - case keyboard: tileentity.Keyboard => - keyboard.setFromEntityPitchAndYaw(player) - keyboard.setFromFacing(side) + ctx.getLevel.getBlockEntity(ctxToUse.getClickedPos) match { + case keyboard: tileentity.Keyboard => // Ignore. case rotatable: tileentity.traits.Rotatable => - rotatable.setFromEntityPitchAndYaw(player) + rotatable.setFromEntityPitchAndYaw(ctxToUse.getPlayer) if (!rotatable.validFacings.contains(rotatable.pitch)) { - rotatable.pitch = rotatable.validFacings.headOption.getOrElse(EnumFacing.NORTH) + rotatable.pitch = rotatable.validFacings.headOption.getOrElse(Direction.NORTH) } if (!rotatable.isInstanceOf[tileentity.RobotProxy]) { rotatable.invertRotation() diff --git a/src/main/scala/li/cil/oc/common/block/Keyboard.scala b/src/main/scala/li/cil/oc/common/block/Keyboard.scala index 0054c5ba37..bc2a5064b7 100644 --- a/src/main/scala/li/cil/oc/common/block/Keyboard.scala +++ b/src/main/scala/li/cil/oc/common/block/Keyboard.scala @@ -2,6 +2,7 @@ package li.cil.oc.common.block import java.util.Random +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Constants import li.cil.oc.api import li.cil.oc.common.block.property.PropertyRotatable @@ -9,123 +10,127 @@ import li.cil.oc.common.tileentity import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedEnumFacing._ import li.cil.oc.util.InventoryUtils +import li.cil.oc.util.RotationHelper +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.material.Material -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.Blocks +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.BlockItemUseContext import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.math.shapes.VoxelShapes +import net.minecraft.state.StateContainer +import net.minecraft.world.IBlockReader +import net.minecraft.world.IWorldReader import net.minecraft.world.World +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -class Keyboard extends SimpleBlock(Material.ROCK) { - setLightOpacity(0) - +class Keyboard(props: Properties) extends SimpleBlock(props) { // For Immibis Microblock support. val ImmibisMicroblocks_TransformableBlockMarker = null - override def createBlockState() = new BlockStateContainer(this, PropertyRotatable.Pitch, PropertyRotatable.Yaw) - - override def getMetaFromState(state: IBlockState): Int = (state.getValue(PropertyRotatable.Pitch).ordinal() << 2) | state.getValue(PropertyRotatable.Yaw).getHorizontalIndex - - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Pitch, EnumFacing.getFront(meta >> 2)).withProperty(PropertyRotatable.Yaw, EnumFacing.getHorizontal(meta & 0x3)) + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Pitch, PropertyRotatable.Yaw) // ----------------------------------------------------------------------- // - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def isFullCube(state: IBlockState): Boolean = false - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false - - override def getBoundingBox(state: IBlockState, world: IBlockAccess, pos: BlockPos): AxisAlignedBB = - world.getTileEntity(pos) match { - case keyboard: tileentity.Keyboard => - val (pitch, yaw) = (keyboard.pitch, keyboard.yaw) - val (forward, up) = pitch match { - case side@(EnumFacing.DOWN | EnumFacing.UP) => (side, yaw) - case _ => (yaw, EnumFacing.UP) - } - val side = forward.getRotation(up) - val sizes = Array(7f / 16f, 4f / 16f, 7f / 16f) - val x0 = -up.getFrontOffsetX * sizes(1) - side.getFrontOffsetX * sizes(2) - forward.getFrontOffsetX * sizes(0) - val x1 = up.getFrontOffsetX * sizes(1) + side.getFrontOffsetX * sizes(2) - forward.getFrontOffsetX * 0.5f - val y0 = -up.getFrontOffsetY * sizes(1) - side.getFrontOffsetY * sizes(2) - forward.getFrontOffsetY * sizes(0) - val y1 = up.getFrontOffsetY * sizes(1) + side.getFrontOffsetY * sizes(2) - forward.getFrontOffsetY * 0.5f - val z0 = -up.getFrontOffsetZ * sizes(1) - side.getFrontOffsetZ * sizes(2) - forward.getFrontOffsetZ * sizes(0) - val z1 = up.getFrontOffsetZ * sizes(1) + side.getFrontOffsetZ * sizes(2) - forward.getFrontOffsetZ * 0.5f - new AxisAlignedBB(x0, y0, z0, x1, y1, z1).offset(0.5, 0.5, 0.5) - case _ => super.getBoundingBox(state, world, pos) + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = { + val (pitch, yaw) = (state.getValue(PropertyRotatable.Pitch), state.getValue(PropertyRotatable.Yaw)) + val (forward, up) = pitch match { + case side@(Direction.DOWN | Direction.UP) => (side, yaw) + case _ => (yaw, Direction.UP) } - - // ----------------------------------------------------------------------- // - - override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = true - - override def preItemRender(metadata: Int) { - GlStateManager.translate(-0.75f, 0, 0) - GlStateManager.scale(1.5f, 1.5f, 1.5f) + val side = forward.getRotation(up) + val sizes = Array(7f / 16f, 4f / 16f, 7f / 16f) + val x0 = -up.getStepX * sizes(1) - side.getStepX * sizes(2) - forward.getStepX * sizes(0) + val x1 = up.getStepX * sizes(1) + side.getStepX * sizes(2) - forward.getStepX * 0.5f + val y0 = -up.getStepY * sizes(1) - side.getStepY * sizes(2) - forward.getStepY * sizes(0) + val y1 = up.getStepY * sizes(1) + side.getStepY * sizes(2) - forward.getStepY * 0.5f + val z0 = -up.getStepZ * sizes(1) - side.getStepZ * sizes(2) - forward.getStepZ * sizes(0) + val z1 = up.getStepZ * sizes(1) + side.getStepZ * sizes(2) - forward.getStepZ * 0.5f + VoxelShapes.box(0.5 + x0, 0.5 + y0, 0.5 + z0, 0.5 + x1, 0.5 + y1, 0.5 + z1) } // ----------------------------------------------------------------------- // - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Keyboard() + override def newBlockEntity(world: IBlockReader) = new tileentity.Keyboard(tileentity.TileEntityTypes.KEYBOARD) // ----------------------------------------------------------------------- // - override def updateTick(world: World, pos: BlockPos, state: IBlockState, rand: Random) = - world.getTileEntity(pos) match { + override def onPlace(state: BlockState, world: World, pos: BlockPos, prevState: BlockState, moved: Boolean): Unit = { + if (!world.isClientSide) { + world.asInstanceOf[ServerWorld].getBlockTicks.scheduleTick(pos, this, 10) + } + } + + override def tick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) = { + world.getBlockEntity(pos) match { case keyboard: tileentity.Keyboard => api.Network.joinOrCreateNetwork(keyboard) case _ => } + world.getBlockTicks.scheduleTick(pos, this, 10) + } - override def canPlaceBlockOnSide(world: World, pos: BlockPos, side: EnumFacing) = { - world.isSideSolid(pos.offset(side.getOpposite), side) && - (world.getTileEntity(pos.offset(side.getOpposite)) match { + override def getStateForPlacement(ctx: BlockItemUseContext): BlockState = { + val (pitch, yaw) = ctx.getClickedFace match { + case side@(Direction.DOWN | Direction.UP) => (side, ctx.getHorizontalDirection) + case side => (Direction.NORTH, side) + } + super.getStateForPlacement(ctx).setValue(PropertyRotatable.Pitch, pitch).setValue(PropertyRotatable.Yaw, yaw) + } + + override def canSurvive(state: BlockState, world: IWorldReader, pos: BlockPos) = { + // Check without the TE because this is called to check if the block may be placed. + val side = state.getValue(PropertyRotatable.Pitch) match { + case pitch@(Direction.UP | Direction.DOWN) => pitch + case _ => state.getValue(PropertyRotatable.Yaw) + } + val sidePos = pos.relative(side.getOpposite) + world.getBlockState(sidePos).isFaceSturdy(world, sidePos, side) && + (world.getBlockEntity(pos.relative(side.getOpposite)) match { case screen: tileentity.Screen => screen.facing != side case _ => true }) } - override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit = - world.getTileEntity(pos) match { - case keyboard: tileentity.Keyboard => - if (!canPlaceBlockOnSide(world, pos, keyboard.facing)) { - world.setBlockToAir(pos) - InventoryUtils.spawnStackInWorld(BlockPosition(pos, world), api.Items.get(Constants.BlockName.Keyboard).createItemStack(1)) - } - case _ => + @Deprecated + override def neighborChanged(state: BlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos, b: Boolean): Unit = + if (!canSurvive(world.getBlockState(pos), world, pos)) { + world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState) + InventoryUtils.spawnStackInWorld(BlockPosition(pos, world), api.Items.get(Constants.BlockName.Keyboard).createItemStack(1)) } - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = adjacencyInfo(world, pos) match { case Some((keyboard, screen, blockPos, facing)) => screen.rightClick(world, blockPos, player, hand, heldItem, facing, 0, 0, 0, force = true) case _ => false } def adjacencyInfo(world: World, pos: BlockPos) = - world.getTileEntity(pos) match { + world.getBlockEntity(pos) match { case keyboard: tileentity.Keyboard => - val blockPos = pos.offset(keyboard.facing.getOpposite) + val blockPos = pos.relative(keyboard.facing.getOpposite) world.getBlockState(blockPos).getBlock match { case screen: Screen => Some((keyboard, screen, blockPos, keyboard.facing.getOpposite)) case _ => // Special case #1: check for screen in front of the keyboard. val forward = keyboard.facing match { - case EnumFacing.UP | EnumFacing.DOWN => keyboard.yaw - case _ => EnumFacing.UP + case Direction.UP | Direction.DOWN => keyboard.yaw + case _ => Direction.UP } - val blockPos = pos.offset(forward) + val blockPos = pos.relative(forward) world.getBlockState(blockPos).getBlock match { case screen: Screen => Some((keyboard, screen, blockPos, forward)) - case _ if keyboard.facing != EnumFacing.UP && keyboard.facing != EnumFacing.DOWN => + case _ if keyboard.facing != Direction.UP && keyboard.facing != Direction.DOWN => // Special case #2: check for screen below keyboards on walls. - val blockPos = pos.offset(forward.getOpposite) + val blockPos = pos.relative(forward.getOpposite) world.getBlockState(blockPos).getBlock match { case screen: Screen => Some((keyboard, screen, blockPos, forward.getOpposite)) case _ => None diff --git a/src/main/scala/li/cil/oc/common/block/Microcontroller.scala b/src/main/scala/li/cil/oc/common/block/Microcontroller.scala index ab5979b96a..465d947cc0 100644 --- a/src/main/scala/li/cil/oc/common/block/Microcontroller.scala +++ b/src/main/scala/li/cil/oc/common/block/Microcontroller.scala @@ -10,75 +10,72 @@ import li.cil.oc.common.Tier import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.common.item.data.MicrocontrollerData import li.cil.oc.common.tileentity -import li.cil.oc.integration.util.ItemBlacklist import li.cil.oc.integration.util.Wrench +import li.cil.oc.server.loot.LootFunctions import li.cil.oc.util.InventoryUtils -import li.cil.oc.util.Rarity import li.cil.oc.util.StackOption._ +import li.cil.oc.util.Tooltip +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumRarity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.loot.LootContext +import net.minecraft.loot.LootParameters +import net.minecraft.state.StateContainer +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.RayTraceResult +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeBlock import scala.reflect.ClassTag -class Microcontroller(protected implicit val tileTag: ClassTag[tileentity.Microcontroller]) extends RedstoneAware with traits.PowerAcceptor with traits.StateAware with traits.CustomDrops[tileentity.Microcontroller] { - setCreativeTab(null) - ItemBlacklist.hide(this) +class Microcontroller(props: Properties) + extends RedstoneAware(props) with IForgeBlock with traits.PowerAcceptor with traits.StateAware { - override def createBlockState() = new BlockStateContainer(this, PropertyRotatable.Facing) - - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Facing, EnumFacing.getHorizontal(meta)) - - override def getMetaFromState(state: IBlockState): Int = state.getValue(PropertyRotatable.Facing).getHorizontalIndex + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Facing) // ----------------------------------------------------------------------- // - override def getPickBlock(state: IBlockState, target: RayTraceResult, world: World, pos: BlockPos, player: EntityPlayer): ItemStack = - world.getTileEntity(pos) match { + override def getPickBlock(state: BlockState, target: RayTraceResult, world: IBlockReader, pos: BlockPos, player: PlayerEntity): ItemStack = + world.getBlockEntity(pos) match { case mcu: tileentity.Microcontroller => mcu.info.copyItemStack() case _ => ItemStack.EMPTY } // ----------------------------------------------------------------------- // - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - super.tooltipTail(metadata, stack, world, tooltip, advanced) + override protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + super.tooltipTail(stack, world, tooltip, advanced) if (KeyBindings.showExtendedTooltips) { val info = new MicrocontrollerData(stack) for (component <- info.components if !component.isEmpty) { - tooltip.add("- " + component.getDisplayName) + tooltip.add(new StringTextComponent("- " + component.getHoverName.getString).setStyle(Tooltip.DefaultStyle)) } } } - override def rarity(stack: ItemStack): EnumRarity = { - val data = new MicrocontrollerData(stack) - Rarity.byTier(data.tier) - } - // ----------------------------------------------------------------------- // override def energyThroughput: Double = Settings.get.caseRate(Tier.One) - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Microcontroller() + override def newBlockEntity(world: IBlockReader) = new tileentity.Microcontroller(tileentity.TileEntityTypes.MICROCONTROLLER) // ----------------------------------------------------------------------- // - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { if (!Wrench.holdsApplicableWrench(player, pos)) { - if (!player.isSneaking) { - if (!world.isRemote) { - world.getTileEntity(pos) match { + if (!player.isCrouching) { + if (!world.isClientSide) { + world.getBlockEntity(pos) match { case mcu: tileentity.Microcontroller => if (mcu.machine.isRunning) mcu.machine.stop() else mcu.machine.start() @@ -88,10 +85,10 @@ class Microcontroller(protected implicit val tileTag: ClassTag[tileentity.Microc true } else if (api.Items.get(heldItem) == api.Items.get(Constants.ItemName.EEPROM)) { - if (!world.isRemote) { - world.getTileEntity(pos) match { + if (!world.isClientSide) { + world.getBlockEntity(pos) match { case mcu: tileentity.Microcontroller => - val newEeprom = player.inventory.decrStackSize(player.inventory.currentItem, 1) + val newEeprom = player.inventory.removeItem(player.inventory.selected, 1) mcu.changeEEPROM(newEeprom) match { case SomeStack(oldEeprom) => InventoryUtils.addToPlayerInventory(oldEeprom, player) case _ => @@ -105,18 +102,39 @@ class Microcontroller(protected implicit val tileTag: ClassTag[tileentity.Microc else false } - override protected def doCustomInit(tileEntity: tileentity.Microcontroller, player: EntityLivingBase, stack: ItemStack): Unit = { - super.doCustomInit(tileEntity, player, stack) - if (!tileEntity.world.isRemote) { - tileEntity.info.load(stack) - tileEntity.snooperNode.changeBuffer(tileEntity.info.storedEnergy - tileEntity.snooperNode.localBuffer) + override def setPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity, stack: ItemStack): Unit = { + super.setPlacedBy(world, pos, state, placer, stack) + world.getBlockEntity(pos) match { + case tileEntity: tileentity.Microcontroller if !world.isClientSide => { + tileEntity.info.loadData(stack) + tileEntity.snooperNode.changeBuffer(tileEntity.info.storedEnergy - tileEntity.snooperNode.localBuffer) + } + case _ => } } - override protected def doCustomDrops(tileEntity: tileentity.Microcontroller, player: EntityPlayer, willHarvest: Boolean): Unit = { - super.doCustomDrops(tileEntity, player, willHarvest) - tileEntity.saveComponents() - tileEntity.info.storedEnergy = tileEntity.snooperNode.localBuffer.toInt - Block.spawnAsEntity(tileEntity.world, tileEntity.getPos, tileEntity.info.createItemStack()) + override def getDrops(state: BlockState, ctx: LootContext.Builder): util.List[ItemStack] = { + val newCtx = ctx.withDynamicDrop(LootFunctions.DYN_ITEM_DATA, (c, f) => { + c.getParamOrNull(LootParameters.BLOCK_ENTITY) match { + case tileEntity: tileentity.Microcontroller => { + tileEntity.saveComponents() + tileEntity.info.storedEnergy = tileEntity.snooperNode.localBuffer.toInt + f.accept(tileEntity.info.createItemStack()) + } + case _ => + } + }) + super.getDrops(state, newCtx) + } + + override def playerWillDestroy(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) { + if (!world.isClientSide && player.isCreative) { + world.getBlockEntity(pos) match { + case tileEntity: tileentity.Microcontroller => + Block.dropResources(state, world, pos, tileEntity, player, player.getMainHandItem) + case _ => + } + } + super.playerWillDestroy(world, pos, state, player) } } diff --git a/src/main/scala/li/cil/oc/common/block/MotionSensor.scala b/src/main/scala/li/cil/oc/common/block/MotionSensor.scala index 82cf657bf9..de4731bf63 100644 --- a/src/main/scala/li/cil/oc/common/block/MotionSensor.scala +++ b/src/main/scala/li/cil/oc/common/block/MotionSensor.scala @@ -1,8 +1,10 @@ package li.cil.oc.common.block import li.cil.oc.common.tileentity +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class MotionSensor extends SimpleBlock { - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.MotionSensor() +class MotionSensor(props: Properties) extends SimpleBlock(props) { + override def newBlockEntity(world: IBlockReader) = new tileentity.MotionSensor(tileentity.TileEntityTypes.MOTION_SENSOR) } diff --git a/src/main/scala/li/cil/oc/common/block/NetSplitter.scala b/src/main/scala/li/cil/oc/common/block/NetSplitter.scala index 76ca51eb69..90f2e57ce9 100644 --- a/src/main/scala/li/cil/oc/common/block/NetSplitter.scala +++ b/src/main/scala/li/cil/oc/common/block/NetSplitter.scala @@ -1,53 +1,39 @@ package li.cil.oc.common.block -import li.cil.oc.common.block.property.PropertyTile import li.cil.oc.common.tileentity import li.cil.oc.integration.util.Wrench -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.BlockRayTraceResult +import net.minecraft.world.IBlockReader import net.minecraft.world.World -import net.minecraftforge.common.property.ExtendedBlockState -import net.minecraftforge.common.property.IExtendedBlockState -class NetSplitter extends RedstoneAware { - override def createBlockState() = new ExtendedBlockState(this, Array.empty, Array(PropertyTile.Tile)) - - override def getExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos): IBlockState = - (state, world.getTileEntity(pos)) match { - case (extendedState: IExtendedBlockState, t: tileentity.NetSplitter) => - extendedState.withProperty(property.PropertyTile.Tile, t) - case _ => state - } - - // ----------------------------------------------------------------------- // - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = false - - // ----------------------------------------------------------------------- // - - override def createNewTileEntity(world: World, meta: Int) = new tileentity.NetSplitter() +class NetSplitter(props: Properties) extends RedstoneAware(props) { + override def newBlockEntity(world: IBlockReader) = new tileentity.NetSplitter(tileentity.TileEntityTypes.NET_SPLITTER) // ----------------------------------------------------------------------- // // NOTE: must not be final for immibis microblocks to work. - override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + override def use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, trace: BlockRayTraceResult): ActionResultType = { if (Wrench.holdsApplicableWrench(player, pos)) { - val sideToToggle = if (player.isSneaking) side.getOpposite else side - world.getTileEntity(pos) match { + val side = trace.getDirection + val sideToToggle = if (player.isCrouching) side.getOpposite else side + world.getBlockEntity(pos) match { case splitter: tileentity.NetSplitter => - if (!world.isRemote) { + if (!world.isClientSide) { val oldValue = splitter.openSides(sideToToggle.ordinal()) splitter.setSideOpen(sideToToggle, !oldValue) } - true - case _ => false + ActionResultType.sidedSuccess(world.isClientSide) + case _ => ActionResultType.PASS } } - else super.onBlockActivated(world, pos, state, player, hand, side, hitX, hitY, hitZ) + else super.use(state, world, pos, player, hand, trace) } } diff --git a/src/main/scala/li/cil/oc/common/block/PowerConverter.scala b/src/main/scala/li/cil/oc/common/block/PowerConverter.scala index 75eee1da08..8ff3f4e6cd 100644 --- a/src/main/scala/li/cil/oc/common/block/PowerConverter.scala +++ b/src/main/scala/li/cil/oc/common/block/PowerConverter.scala @@ -1,54 +1,12 @@ package li.cil.oc.common.block -import java.text.DecimalFormat -import java.util - import li.cil.oc.Settings import li.cil.oc.common.tileentity -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.ItemBlacklist -import li.cil.oc.util.Tooltip -import net.minecraft.client.util.ITooltipFlag -import net.minecraft.item.ItemStack -import net.minecraft.world.World - -class PowerConverter extends SimpleBlock with traits.PowerAcceptor { - if (Settings.get.ignorePower) { - setCreativeTab(null) - ItemBlacklist.hide(this) - } - - private val formatter = new DecimalFormat("#.#") - - // ----------------------------------------------------------------------- // - - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - super.tooltipTail(metadata, stack, world, tooltip, advanced) -// TODO more generic way of integration modules of power providing mods to provide tooltip lines -// if (Mods.Factorization.isAvailable) { -// addRatio(tooltip, "Factorization", Settings.get.ratioFactorization) -// } - if (Mods.IndustrialCraft2.isModAvailable) { - addRatio(tooltip, "IndustrialCraft2", Settings.get.ratioIndustrialCraft2) - } - } - - private def addExtension(x: Double) = - if (x >= 1e9) formatter.format(x / 1e9) + "G" - else if (x >= 1e6) formatter.format(x / 1e6) + "M" - else if (x >= 1e3) formatter.format(x / 1e3) + "K" - else formatter.format(x) - - private def addRatio(tooltip: util.List[String], name: String, ratio: Double) { - val (a, b) = - if (ratio > 1) (1.0, ratio) - else (1.0 / ratio, 1.0) - tooltip.addAll(Tooltip.get(getClass.getSimpleName.toLowerCase + "." + name, addExtension(a), addExtension(b))) - } - - // ----------------------------------------------------------------------- // +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.world.IBlockReader +class PowerConverter(props: Properties) extends SimpleBlock(props) with traits.PowerAcceptor { override def energyThroughput: Double = Settings.get.powerConverterRate - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.PowerConverter() + override def newBlockEntity(world: IBlockReader) = new tileentity.PowerConverter(tileentity.TileEntityTypes.POWER_CONVERTER) } diff --git a/src/main/scala/li/cil/oc/common/block/PowerDistributor.scala b/src/main/scala/li/cil/oc/common/block/PowerDistributor.scala index ab71ceb3a5..d12d940ae5 100644 --- a/src/main/scala/li/cil/oc/common/block/PowerDistributor.scala +++ b/src/main/scala/li/cil/oc/common/block/PowerDistributor.scala @@ -1,9 +1,11 @@ package li.cil.oc.common.block import li.cil.oc.common.tileentity +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class PowerDistributor extends SimpleBlock { - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.PowerDistributor() +class PowerDistributor(props: Properties) extends SimpleBlock(props) { + override def newBlockEntity(world: IBlockReader) = new tileentity.PowerDistributor(tileentity.TileEntityTypes.POWER_DISTRIBUTOR) } diff --git a/src/main/scala/li/cil/oc/common/block/Print.scala b/src/main/scala/li/cil/oc/common/block/Print.scala index e385129aa7..95152f23a1 100644 --- a/src/main/scala/li/cil/oc/common/block/Print.scala +++ b/src/main/scala/li/cil/oc/common/block/Print.scala @@ -5,148 +5,108 @@ import java.util.Random import li.cil.oc.Localization import li.cil.oc.Settings -import li.cil.oc.common.block.property.PropertyTile import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.tileentity -import li.cil.oc.integration.util.ItemBlacklist -import li.cil.oc.util.InventoryUtils -import net.minecraft.block.state.IBlockState +import li.cil.oc.server.loot.LootFunctions +import li.cil.oc.util.Tooltip +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLiving.SpawnPlacementType -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util._ -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.loot.LootContext +import net.minecraft.loot.LootParameters +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.BlockRayTraceResult import net.minecraft.util.math.RayTraceResult -import net.minecraft.util.math.Vec3d -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World -import net.minecraftforge.common.property.ExtendedBlockState -import net.minecraftforge.common.property.IExtendedBlockState +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.common.extensions.IForgeBlock -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.reflect.ClassTag -class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends RedstoneAware with traits.CustomDrops[tileentity.Print] { - setLightOpacity(1) - setHardness(1) - setCreativeTab(null) - ItemBlacklist.hide(this) +class Print(props: Properties) extends RedstoneAware(props) with IForgeBlock { + @Deprecated + override def propagatesSkylightDown(state: BlockState, world: IBlockReader, pos: BlockPos) = false // ----------------------------------------------------------------------- // - override def createBlockState() = new ExtendedBlockState(this, Array.empty, Array(PropertyTile.Tile)) - - override def getExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos): IBlockState = - (state, world.getTileEntity(pos)) match { - case (extendedState: IExtendedBlockState, t: tileentity.Print) => - extendedState.withProperty(property.PropertyTile.Tile, t) - case _ => state - } - - // ----------------------------------------------------------------------- // - - override def canRenderInLayer(state: IBlockState, layer: BlockRenderLayer): Boolean = layer == BlockRenderLayer.CUTOUT_MIPPED - - override protected def tooltipBody(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) = { - super.tooltipBody(metadata, stack, world, tooltip, advanced) + override protected def tooltipBody(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) = { + super.tooltipBody(stack, world, tooltip, advanced) val data = new PrintData(stack) - data.tooltip.foreach(s => tooltip.addAll(s.lines.toIterable)) + data.tooltip.foreach(s => tooltip.addAll(s.lines.map(new StringTextComponent(_).setStyle(Tooltip.DefaultStyle)).toIterable)) } - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) = { - super.tooltipTail(metadata, stack, world, tooltip, advanced) + override protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) = { + super.tooltipTail(stack, world, tooltip, advanced) val data = new PrintData(stack) if (data.isBeaconBase) { - tooltip.add(Localization.Tooltip.PrintBeaconBase) + tooltip.add(new StringTextComponent(Localization.Tooltip.PrintBeaconBase).setStyle(Tooltip.DefaultStyle)) } if (data.emitRedstone) { - tooltip.add(Localization.Tooltip.PrintRedstoneLevel(data.redstoneLevel)) + tooltip.add(new StringTextComponent(Localization.Tooltip.PrintRedstoneLevel(data.redstoneLevel)).setStyle(Tooltip.DefaultStyle)) } if (data.emitLight) { - tooltip.add(Localization.Tooltip.PrintLightValue(data.lightLevel)) + tooltip.add(new StringTextComponent(Localization.Tooltip.PrintLightValue(data.lightLevel)).setStyle(Tooltip.DefaultStyle)) } } - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def getLightValue(state: IBlockState, world: IBlockAccess, pos: BlockPos): Int = + override def getLightValue(state: BlockState, world: IBlockReader, pos: BlockPos): Int = world match { - case world: World if world.isBlockLoaded(pos) => world.getTileEntity(pos) match { + case world: World if world.isLoaded(pos) => world.getBlockEntity(pos) match { case print: tileentity.Print => print.data.lightLevel case _ => super.getLightValue(state, world, pos) } case _ => super.getLightValue(state, world, pos) } - override def getLightOpacity(state: IBlockState, world: IBlockAccess, pos: BlockPos): Int = + @Deprecated + override def getLightBlock(state: BlockState, world: IBlockReader, pos: BlockPos): Int = world match { - case world: World if world.isBlockLoaded(pos) => world.getTileEntity(pos) match { + case world: World if world.isLoaded(pos) => world.getBlockEntity(pos) match { case print: tileentity.Print if Settings.get.printsHaveOpacity => (print.data.opacity * 4).toInt - case _ => super.getLightOpacity(state, world, pos) + case _ => super.getLightBlock(state, world, pos) } - case _ => super.getLightOpacity(state, world, pos) - } - - override def isFullCube(state: IBlockState): Boolean = false - - override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = true - - override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = - world.getTileEntity(pos) match { - case print: tileentity.Print => print.isSideSolid(side) - case _ => false + case _ => super.getLightBlock(state, world, pos) } - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = - isBlockSolid(world, pos, side) - - override def getPickBlock(state: IBlockState, target: RayTraceResult, world: World, pos: BlockPos, player: EntityPlayer): ItemStack = { - world.getTileEntity(pos) match { + override def getPickBlock(state: BlockState, target: RayTraceResult, world: IBlockReader, pos: BlockPos, player: PlayerEntity): ItemStack = { + world.getBlockEntity(pos) match { case print: tileentity.Print => print.data.createItemStack() case _ => ItemStack.EMPTY } } - override def getBoundingBox(state: IBlockState, world: IBlockAccess, pos: BlockPos): AxisAlignedBB = { - world.getTileEntity(pos) match { - case print: tileentity.Print => print.bounds - case _ => super.getBoundingBox(state, world, pos) + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = { + world.getBlockEntity(pos) match { + case print: tileentity.Print => print.shape + case _ => super.getShape(state, world, pos, ctx) } } - override def addCollisionBoxToList(state: IBlockState, world: World, pos: BlockPos, mask: AxisAlignedBB, list: util.List[AxisAlignedBB], entity: Entity, par7: Boolean): Unit = { - world.getTileEntity(pos) match { - case print: tileentity.Print => print.addCollisionBoxesToList(mask, list, pos) - case _ => super.addCollisionBoxToList(state, world, pos, mask, list, entity, par7) - } - } + def tickRate(world: World) = 20 - override def collisionRayTrace(state: IBlockState, world: World, pos: BlockPos, start: Vec3d, end: Vec3d): RayTraceResult = { - world.getTileEntity(pos) match { - case print: tileentity.Print => print.rayTrace(start, end, pos) - case _ => super.collisionRayTrace(state, world, pos, start, end) - } - } - - override def canCreatureSpawn(state: IBlockState, world: IBlockAccess, pos: BlockPos, `type`: SpawnPlacementType): Boolean = true - - override def tickRate(world: World) = 20 - - override def updateTick(world: World, pos: BlockPos, state: IBlockState, rand: Random): Unit = { - if (!world.isRemote) world.getTileEntity(pos) match { + override def tick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random): Unit = { + if (!world.isClientSide) world.getBlockEntity(pos) match { case print: tileentity.Print => if (print.state) print.toggleState() - if (print.state) world.scheduleUpdate(pos, state.getBlock, tickRate(world)) case _ => } } - override def isBeaconBase(world: IBlockAccess, pos: BlockPos, beacon: BlockPos): Boolean = { - world.getTileEntity(pos) match { + @Deprecated + def isBeaconBase(world: IBlockReader, pos: BlockPos, beacon: BlockPos): Boolean = { + world.getBlockEntity(pos) match { case print: tileentity.Print => print.data.isBeaconBase case _ => false } @@ -154,41 +114,49 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends // ----------------------------------------------------------------------- // - override def createNewTileEntity(worldIn: World, meta: Int) = new tileentity.Print() + override def newBlockEntity(worldIn: IBlockReader) = new tileentity.Print(tileentity.TileEntityTypes.PRINT) // ----------------------------------------------------------------------- // - override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - world.getTileEntity(pos) match { - case print: tileentity.Print => print.activate() - case _ => super.onBlockActivated(world, pos, state, player, hand, side, hitX, hitY, hitZ) + override def use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, trace: BlockRayTraceResult): ActionResultType = { + world.getBlockEntity(pos) match { + case print: tileentity.Print => if (print.activate()) ActionResultType.sidedSuccess(world.isClientSide) else ActionResultType.PASS + case _ => super.use(state, world, pos, player, hand, trace) } } - override protected def doCustomInit(tileEntity: tileentity.Print, player: EntityLivingBase, stack: ItemStack): Unit = { - super.doCustomInit(tileEntity, player, stack) - tileEntity.data.load(stack) - tileEntity.updateBounds() - tileEntity.updateRedstone() - tileEntity.getWorld.checkLight(tileEntity.getPos) - } - - override protected def doCustomDrops(tileEntity: tileentity.Print, player: EntityPlayer, willHarvest: Boolean): Unit = { - super.doCustomDrops(tileEntity, player, willHarvest) - if (!player.capabilities.isCreativeMode) { - InventoryUtils.spawnStackInWorld(tileEntity.position, tileEntity.data.createItemStack()) + override def onRemove(state: BlockState, world: World, pos: BlockPos, newState: BlockState, moved: Boolean): Unit = { + world.getBlockEntity(pos) match { + case print: tileentity.Print if print.data.emitRedstone(print.state) => + world.updateNeighborsAt(pos, this) + for (side <- Direction.values) { + world.updateNeighborsAt(pos.relative(side), this) + } + case _ => } + super.onRemove(state, world, pos, newState, moved) } - override def breakBlock(world: World, pos: BlockPos, state: IBlockState): Unit = { - world.getTileEntity(pos) match { - case print: tileentity.Print if print.data.emitRedstone(print.state) => - world.notifyNeighborsOfStateChange(pos, this, false) - for (side <- EnumFacing.values) { - world.notifyNeighborsOfStateChange(pos.offset(side), this, false) - } + override def setPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity, stack: ItemStack): Unit = { + super.setPlacedBy(world, pos, state, placer, stack) + world.getBlockEntity(pos) match { + case tileEntity: tileentity.Print => { + tileEntity.data.loadData(stack) + tileEntity.updateShape() + tileEntity.updateRedstone() + tileEntity.getLevel.getLightEngine.checkBlock(tileEntity.getBlockPos) + } case _ => } - super.breakBlock(world, pos, state) + } + + override def getDrops(state: BlockState, ctx: LootContext.Builder): util.List[ItemStack] = { + val newCtx = ctx.withDynamicDrop(LootFunctions.DYN_ITEM_DATA, (c, f) => { + c.getParamOrNull(LootParameters.BLOCK_ENTITY) match { + case tileEntity: tileentity.Print => f.accept(tileEntity.data.createItemStack()) + case _ => + } + }) + super.getDrops(state, newCtx) } } diff --git a/src/main/scala/li/cil/oc/common/block/Printer.scala b/src/main/scala/li/cil/oc/common/block/Printer.scala index 78bc42fd20..90cf805894 100644 --- a/src/main/scala/li/cil/oc/common/block/Printer.scala +++ b/src/main/scala/li/cil/oc/common/block/Printer.scala @@ -1,25 +1,35 @@ package li.cil.oc.common.block -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.tileentity -import net.minecraft.block.state.IBlockState -import net.minecraft.util.EnumFacing +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Block +import net.minecraft.block.BlockState +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.shapes.IBooleanFunction +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.math.shapes.VoxelShapes +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Printer extends SimpleBlock with traits.StateAware with traits.GUI { - override def isOpaqueCube(state: IBlockState): Boolean = false +class Printer(props: Properties) extends SimpleBlock(props) with traits.StateAware with traits.GUI { + val blockShape = { + val base = Block.box(0, 0, 0, 16, 8, 16) + val pillars = VoxelShapes.or(Block.box(0, 8, 0, 3, 13, 3), Block.box(13, 8, 0, 16, 13, 3), + Block.box(13, 8, 13, 16, 13, 16), Block.box(0, 8, 13, 3, 13, 16)) + val ring = VoxelShapes.join(Block.box(0, 13, 0, 16, 16, 16), + Block.box(3, 13, 3, 13, 16, 13), IBooleanFunction.ONLY_FIRST) + VoxelShapes.or(base, pillars, ring) + } - override def isFullCube(state: IBlockState): Boolean = false + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = blockShape - override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Printer => ContainerTypes.openPrinterGui(player, te) + case _ => + } - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN - - // ----------------------------------------------------------------------- // - - override def guiType = GuiType.Printer - - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Printer() + override def newBlockEntity(world: IBlockReader) = new tileentity.Printer(tileentity.TileEntityTypes.PRINTER) } diff --git a/src/main/scala/li/cil/oc/common/block/Rack.scala b/src/main/scala/li/cil/oc/common/block/Rack.scala index e2e20051ed..f5de252cb9 100644 --- a/src/main/scala/li/cil/oc/common/block/Rack.scala +++ b/src/main/scala/li/cil/oc/common/block/Rack.scala @@ -2,124 +2,57 @@ package li.cil.oc.common.block import li.cil.oc.Settings import li.cil.oc.api.component.RackMountable -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.common.tileentity -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Block +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumFacing.Axis -import net.minecraft.util.EnumHand -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.state.StateContainer +import net.minecraft.util.Direction +import net.minecraft.util.Direction.Axis +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.RayTraceResult import net.minecraft.util.math.RayTraceResult -import net.minecraft.util.math.Vec3d -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.world.IBlockReader import net.minecraft.world.World -import net.minecraftforge.common.property.ExtendedBlockState -import net.minecraftforge.common.property.IExtendedBlockState -class Rack extends RedstoneAware with traits.PowerAcceptor with traits.StateAware with traits.GUI { - override def createBlockState() = new ExtendedBlockState(this, Array(PropertyRotatable.Facing), Array(property.PropertyTile.Tile)) - - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Facing, EnumFacing.getHorizontal(meta)) - - override def getMetaFromState(state: IBlockState): Int = state.getValue(PropertyRotatable.Facing).getHorizontalIndex - - override def getExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos): IBlockState = { - ((state, world.getTileEntity(pos)) match { - case (extendedState: IExtendedBlockState, tile: tileentity.traits.TileEntity) => - extendedState.withProperty(property.PropertyTile.Tile, tile) - case _ => state - }).withProperty(PropertyRotatable.Facing, getFacing(world, pos)) - } - - // @SideOnly(Side.CLIENT) - // override def getMixedBrightnessForBlock(world: IBlockAccess, pos: BlockPos) = { - // if (pos.getY >= 0 && pos.getY < 256) world.getTileEntity(pos) match { - // case rack: tileentity.Rack => - // def brightness(pos: BlockPos) = world.getCombinedLight(pos, world.getBlockState(pos).getBlock.getLightValue(world, pos)) - // val value = brightness(pos.offset(rack.facing)) - // val skyBrightness = (value >> 20) & 15 - // val blockBrightness = (value >> 4) & 15 - // ((skyBrightness * 3 / 4) << 20) | ((blockBrightness * 3 / 4) << 4) - // case _ => super.getMixedBrightnessForBlock(world, pos) - // } - // else super.getMixedBrightnessForBlock(world, pos) - // } - - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def isFullCube(state: IBlockState): Boolean = false - - override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.SOUTH - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = toLocal(world, pos, side) != EnumFacing.SOUTH +class Rack(props: Properties) extends RedstoneAware(props) with traits.PowerAcceptor with traits.StateAware with traits.GUI { + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Facing) // ----------------------------------------------------------------------- // override def energyThroughput = Settings.get.serverRackRate - override def guiType = GuiType.Rack + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Rack => ContainerTypes.openRackGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Rack() + override def newBlockEntity(world: IBlockReader) = new tileentity.Rack(tileentity.TileEntityTypes.RACK) // ----------------------------------------------------------------------- // - final val collisionBounds = Array( - new AxisAlignedBB(0, 0, 0, 1, 1 / 16f, 1), - new AxisAlignedBB(0, 15 / 16f, 0, 1, 1, 1), - new AxisAlignedBB(0, 0, 0, 1, 1, 1 / 16f), - new AxisAlignedBB(0, 0, 15 / 16f, 1, 1, 1), - new AxisAlignedBB(0, 0, 0, 1 / 16f, 1, 1), - new AxisAlignedBB(15 / 16f, 0, 0, 1, 1, 1), - new AxisAlignedBB(0.5f / 16f, 0.5f / 16f, 0.5f / 16f, 15.5f / 16f, 15.5f / 16f, 15.5f / 16f) - ) - - override def collisionRayTrace(state: IBlockState, world: World, pos: BlockPos, start: Vec3d, end: Vec3d): RayTraceResult = { - world.getTileEntity(pos) match { - case rack: tileentity.Rack => - var closestDistance = Double.PositiveInfinity - var closest: Option[RayTraceResult] = None - - def intersect(bounds: AxisAlignedBB): Unit = { - val hit = bounds.offset(pos.getX, pos.getY, pos.getZ).calculateIntercept(start, end) - if (hit != null) { - val distance = hit.hitVec.distanceTo(start) - if (distance < closestDistance) { - closestDistance = distance - closest = Option(hit) - } - } - } - val facings = EnumFacing.VALUES - for (i <- 0 until facings.length) { - if (rack.facing != facings(i)) { - intersect(collisionBounds(i)) - } - } - intersect(collisionBounds.last) - closest.map(hit => new RayTraceResult(hit.hitVec, hit.sideHit, pos)).orNull - case _ => super.collisionRayTrace(state, world, pos, start, end) - } - } - - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - world.getTileEntity(pos) match { + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + world.getBlockEntity(pos) match { case rack: tileentity.Rack => rack.slotAt(side, hitX, hitY, hitZ) match { case Some(slot) => // Snap to grid to get same behavior on client and server... - val hitVec = new Vec3d((hitX * 16f).toInt / 16f, (hitY * 16f).toInt / 16f, (hitZ * 16f).toInt / 16f) + val hitVec = new Vector3d((hitX * 16f).toInt / 16f, (hitY * 16f).toInt / 16f, (hitZ * 16f).toInt / 16f) val rotation = side match { - case EnumFacing.WEST => Math.toRadians(90).toFloat - case EnumFacing.NORTH => Math.toRadians(180).toFloat - case EnumFacing.EAST => Math.toRadians(270).toFloat + case Direction.WEST => Math.toRadians(90).toFloat + case Direction.NORTH => Math.toRadians(180).toFloat + case Direction.EAST => Math.toRadians(270).toFloat case _ => 0 } // Rotate *centers* of pixels to keep association when reversing axis. - val localHitVec = rotate(hitVec.addVector(-0.5 + 1 / 32f, -0.5 + 1 / 32f, -0.5 + 1 / 32f), rotation).addVector(0.5 - 1 / 32f, 0.5 - 1 / 32f, 0.5 - 1 / 32f) + val localHitVec = rotate(hitVec.add(-0.5 + 1 / 32f, -0.5 + 1 / 32f, -0.5 + 1 / 32f), rotation).add(0.5 - 1 / 32f, 0.5 - 1 / 32f, 0.5 - 1 / 32f) val globalX = (localHitVec.x * 16.05f).toInt // [0, 15], work around floating point inaccuracies val globalY = (localHitVec.y * 16.05f).toInt // [0, 15], work around floating point inaccuracies val localX = (if (side.getAxis != Axis.Z) 15 - globalX else globalX) - 1 @@ -135,9 +68,9 @@ class Rack extends RedstoneAware with traits.PowerAcceptor with traits.StateAwar super.localOnBlockActivated(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ) } - def rotate(v: Vec3d, t: Float): Vec3d = { + def rotate(v: Vector3d, t: Float): Vector3d = { val cos = Math.cos(t) val sin = Math.sin(t) - new Vec3d(v.x * cos - v.z * sin, v.y, v.x * sin + v.z * cos) + new Vector3d(v.x * cos - v.z * sin, v.y, v.x * sin + v.z * cos) } } diff --git a/src/main/scala/li/cil/oc/common/block/Raid.scala b/src/main/scala/li/cil/oc/common/block/Raid.scala index b230a8b924..0bb5fb63aa 100644 --- a/src/main/scala/li/cil/oc/common/block/Raid.scala +++ b/src/main/scala/li/cil/oc/common/block/Raid.scala @@ -3,81 +3,113 @@ package li.cil.oc.common.block import java.util import li.cil.oc.client.KeyBindings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.common.item.data.RaidData import li.cil.oc.common.tileentity +import li.cil.oc.server.loot.LootFunctions +import li.cil.oc.util.Tooltip +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.state.StateContainer +import net.minecraft.loot.LootContext +import net.minecraft.loot.LootParameters +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeBlock import scala.reflect.ClassTag -class Raid(protected implicit val tileTag: ClassTag[tileentity.Raid]) extends SimpleBlock with traits.GUI with traits.CustomDrops[tileentity.Raid] { - override def createBlockState() = new BlockStateContainer(this, PropertyRotatable.Facing) +class Raid(props: Properties) extends SimpleBlock(props) with IForgeBlock with traits.GUI { - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Facing, EnumFacing.getHorizontal(meta)) + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Facing) - override def getMetaFromState(state: IBlockState): Int = state.getValue(PropertyRotatable.Facing).getHorizontalIndex - - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - super.tooltipTail(metadata, stack, world, tooltip, advanced) + override protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + super.tooltipTail(stack, world, tooltip, advanced) if (KeyBindings.showExtendedTooltips) { val data = new RaidData(stack) for (disk <- data.disks if !disk.isEmpty) { - tooltip.add("- " + disk.getDisplayName) + tooltip.add(new StringTextComponent("- " + disk.getHoverName.getString).setStyle(Tooltip.DefaultStyle)) } } } // ----------------------------------------------------------------------- // - override def guiType = GuiType.Raid + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Raid => ContainerTypes.openRaidGui(player, te) + case _ => + } - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Raid() + override def newBlockEntity(world: IBlockReader) = new tileentity.Raid(tileentity.TileEntityTypes.RAID) // ----------------------------------------------------------------------- // - override def hasComparatorInputOverride(state: IBlockState): Boolean = true + override def hasAnalogOutputSignal(state: BlockState): Boolean = true - override def getComparatorInputOverride(state: IBlockState, world: World, pos: BlockPos): Int = - world.getTileEntity(pos) match { + override def getAnalogOutputSignal(state: BlockState, world: World, pos: BlockPos): Int = + world.getBlockEntity(pos) match { case raid: tileentity.Raid if raid.presence.forall(ok => ok) => 15 case _ => 0 } - override protected def doCustomInit(tileEntity: tileentity.Raid, player: EntityLivingBase, stack: ItemStack): Unit = { - super.doCustomInit(tileEntity, player, stack) - if (!tileEntity.world.isRemote) { - val data = new RaidData(stack) - for (i <- 0 until math.min(data.disks.length, tileEntity.getSizeInventory)) { - tileEntity.setInventorySlotContents(i, data.disks(i)) - } - data.label.foreach(tileEntity.label.setLabel) - if (!data.filesystem.hasNoTags) { - tileEntity.tryCreateRaid(data.filesystem.getCompoundTag("node").getString("address")) - tileEntity.filesystem.foreach(_.load(data.filesystem)) + override def setPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity, stack: ItemStack): Unit = { + super.setPlacedBy(world, pos, state, placer, stack) + world.getBlockEntity(pos) match { + case tileEntity: tileentity.Raid if !world.isClientSide => { + val data = new RaidData(stack) + for (i <- 0 until math.min(data.disks.length, tileEntity.getContainerSize)) { + tileEntity.setItem(i, data.disks(i)) + } + data.label.foreach(tileEntity.label.setLabel) + if (!data.filesystem.isEmpty) { + tileEntity.tryCreateRaid(data.filesystem.getCompound("node").getString("address")) + tileEntity.filesystem.foreach(_.loadData(data.filesystem)) + } } + case _ => } } - override protected def doCustomDrops(tileEntity: tileentity.Raid, player: EntityPlayer, willHarvest: Boolean): Unit = { - super.doCustomDrops(tileEntity, player, willHarvest) - val stack = createItemStack() - if (tileEntity.items.exists(!_.isEmpty)) { - val data = new RaidData() - data.disks = tileEntity.items.clone() - tileEntity.filesystem.foreach(_.save(data.filesystem)) - data.label = Option(tileEntity.label.getLabel) - data.save(stack) + override def getDrops(state: BlockState, ctx: LootContext.Builder): util.List[ItemStack] = { + val newCtx = ctx.withDynamicDrop(LootFunctions.DYN_ITEM_DATA, (c, f) => { + c.getParamOrNull(LootParameters.BLOCK_ENTITY) match { + case tileEntity: tileentity.Raid => { + val stack = createItemStack() + if (tileEntity.items.exists(!_.isEmpty)) { + val data = new RaidData() + data.disks = tileEntity.items.clone() + tileEntity.filesystem.foreach(_.saveData(data.filesystem)) + data.label = Option(tileEntity.label.getLabel) + data.saveData(stack) + } + f.accept(stack) + } + case _ => + } + }) + super.getDrops(state, newCtx) + } + + override def playerWillDestroy(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) { + if (!world.isClientSide && player.isCreative) { + world.getBlockEntity(pos) match { + case tileEntity: tileentity.Raid if tileEntity.items.exists(!_.isEmpty) => + Block.dropResources(state, world, pos, tileEntity, player, player.getMainHandItem) + case _ => + } } - Block.spawnAsEntity(tileEntity.world, tileEntity.getPos, stack) + super.playerWillDestroy(world, pos, state, player) } } diff --git a/src/main/scala/li/cil/oc/common/block/Redstone.scala b/src/main/scala/li/cil/oc/common/block/Redstone.scala index 3e4288b422..3cc588e5f5 100644 --- a/src/main/scala/li/cil/oc/common/block/Redstone.scala +++ b/src/main/scala/li/cil/oc/common/block/Redstone.scala @@ -5,24 +5,27 @@ import java.util import li.cil.oc.common.tileentity import li.cil.oc.integration.Mods import li.cil.oc.util.Tooltip +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Redstone extends RedstoneAware { - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - super.tooltipTail(metadata, stack, world, tooltip, advanced) +import scala.collection.convert.ImplicitConversionsToScala._ + +class Redstone(props: Properties) extends RedstoneAware(props) { + override protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + super.tooltipTail(stack, world, tooltip, advanced) // todo more generic way for redstone mods to provide lines if (Mods.ProjectRedTransmission.isModAvailable) { - tooltip.addAll(Tooltip.get("RedstoneCard.ProjectRed")) - } - if (Mods.Charset.isModAvailable) { - tooltip.addAll(Tooltip.get("RedstoneCard.Charset")) + for (curr <- Tooltip.get("redstonecard.ProjectRed")) tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) } } // ----------------------------------------------------------------------- // - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Redstone() + override def newBlockEntity(world: IBlockReader) = new tileentity.Redstone(tileentity.TileEntityTypes.REDSTONE_IO) } diff --git a/src/main/scala/li/cil/oc/common/block/RedstoneAware.scala b/src/main/scala/li/cil/oc/common/block/RedstoneAware.scala index 8be1840b00..868b7e89ce 100644 --- a/src/main/scala/li/cil/oc/common/block/RedstoneAware.scala +++ b/src/main/scala/li/cil/oc/common/block/RedstoneAware.scala @@ -1,35 +1,38 @@ package li.cil.oc.common.block import li.cil.oc.common.tileentity +import net.minecraft.block.AbstractBlock.Properties import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState -import net.minecraft.util.EnumFacing +import net.minecraft.block.BlockState +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IBlockReader import net.minecraft.world.World -abstract class RedstoneAware extends SimpleBlock { - override def canProvidePower(state: IBlockState): Boolean = true +abstract class RedstoneAware(props: Properties) extends SimpleBlock(props) { + override def isSignalSource(state: BlockState): Boolean = true - override def canConnectRedstone(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = - world.getTileEntity(pos) match { + override def canConnectRedstone(state: BlockState, world: IBlockReader, pos: BlockPos, side: Direction): Boolean = + world.getBlockEntity(pos) match { case redstone: tileentity.traits.RedstoneAware => redstone.isOutputEnabled case _ => false } - override def getStrongPower(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = - getWeakPower(state, world, pos, side) + override def getDirectSignal(state: BlockState, world: IBlockReader, pos: BlockPos, side: Direction) = + getSignal(state, world, pos, side) - override def getWeakPower(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = - world.getTileEntity(pos) match { + @Deprecated + override def getSignal(state: BlockState, world: IBlockReader, pos: BlockPos, side: Direction) = + world.getBlockEntity(pos) match { case redstone: tileentity.traits.RedstoneAware if side != null => redstone.getOutput(side.getOpposite) max 0 - case _ => super.getWeakPower(state, world, pos, side) + case _ => super.getSignal(state, world, pos, side) } // ----------------------------------------------------------------------- // - override def neighborChanged(state: IBlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos): Unit = { - world.getTileEntity(pos) match { + @Deprecated + override def neighborChanged(state: BlockState, world: World, pos: BlockPos, block: Block, fromPos: BlockPos, b: Boolean): Unit = { + world.getBlockEntity(pos) match { case redstone: tileentity.traits.RedstoneAware => redstone.checkRedstoneInputChanged() case _ => // Ignore. } diff --git a/src/main/scala/li/cil/oc/common/block/Relay.scala b/src/main/scala/li/cil/oc/common/block/Relay.scala index 2d9ea12b20..9bc69b21a0 100644 --- a/src/main/scala/li/cil/oc/common/block/Relay.scala +++ b/src/main/scala/li/cil/oc/common/block/Relay.scala @@ -1,14 +1,21 @@ package li.cil.oc.common.block import li.cil.oc.Settings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.tileentity +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.util.math.BlockPos +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Relay extends SimpleBlock with traits.GUI with traits.PowerAcceptor { - override def guiType = GuiType.Relay +class Relay(props: Properties) extends SimpleBlock(props) with traits.GUI with traits.PowerAcceptor { + override def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos): Unit = world.getBlockEntity(pos) match { + case te: tileentity.Relay => ContainerTypes.openRelayGui(player, te) + case _ => + } override def energyThroughput = Settings.get.accessPointRate - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Relay() + override def newBlockEntity(world: IBlockReader) = new tileentity.Relay(tileentity.TileEntityTypes.RELAY) } diff --git a/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala b/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala index 7d8e890daf..4cf5fbdf8b 100644 --- a/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala +++ b/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala @@ -5,105 +5,81 @@ import java.util.Random import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.api -import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.tileentity -import li.cil.oc.integration.util.ItemBlacklist -import li.cil.oc.util.Rarity -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Blocks +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.fluid.FluidState import net.minecraft.item.ItemStack -import net.minecraft.util._ -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.BlockRayTraceResult import net.minecraft.util.math.RayTraceResult -import net.minecraft.util.math.Vec3i -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.world.IBlockReader import net.minecraft.world.World +import net.minecraft.world.server.ServerWorld -class RobotAfterimage extends SimpleBlock { - setLightOpacity(0) - setCreativeTab(null) - ItemBlacklist.hide(this) - - // ----------------------------------------------------------------------- // - - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def isFullCube(state: IBlockState): Boolean = false - - override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false - - override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false - - override def getPickBlock(state: IBlockState, target: RayTraceResult, world: World, pos: BlockPos, player: EntityPlayer): ItemStack = +class RobotAfterimage(props: Properties) extends SimpleBlock(props) { + override def getPickBlock(state: BlockState, target: RayTraceResult, world: IBlockReader, pos: BlockPos, player: PlayerEntity): ItemStack = findMovingRobot(world, pos) match { case Some(robot) => robot.info.createItemStack() case _ => ItemStack.EMPTY } - override def getBoundingBox(state: IBlockState, world: IBlockAccess, pos: BlockPos): AxisAlignedBB = { + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = { findMovingRobot(world, pos) match { case Some(robot) => - val block = robot.getBlockType.asInstanceOf[SimpleBlock] - val bounds = block.getBoundingBox(state, world, robot.getPos) - val delta = robot.moveFrom.fold(Vec3i.NULL_VECTOR)(vec => { - val blockPos = robot.getPos + val block = robot.getBlockState.getBlock.asInstanceOf[SimpleBlock] + val shape = block.getShape(state, world, robot.getBlockPos, ctx) + val delta = robot.moveFrom.fold(BlockPos.ZERO)(vec => { + val blockPos = robot.getBlockPos new BlockPos(blockPos.getX - vec.getX, blockPos.getY - vec.getY, blockPos.getZ - vec.getZ) }) - bounds.offset(delta.getX, delta.getY, delta.getZ) - case _ => super.getBoundingBox(state, world, pos) + shape.move(delta.getX, delta.getY, delta.getZ) + case _ => super.getShape(state, world, pos, ctx) } } // ----------------------------------------------------------------------- // - override def hasTileEntity(state: IBlockState): Boolean = false - - override def createNewTileEntity(worldIn: World, meta: Int) = null - - // ----------------------------------------------------------------------- // - - override def rarity(stack: ItemStack) = { - val data = new RobotData(stack) - Rarity.byTier(data.tier) - } - - override def isAir(state: IBlockState, world: IBlockAccess, pos: BlockPos): Boolean = true - - // ----------------------------------------------------------------------- // - - override def onBlockAdded(world: World, pos: BlockPos, state: IBlockState) { - world.scheduleUpdate(pos, this, Math.max((Settings.get.moveDelay * 20).toInt, 1) - 1) + override def onPlace(state: BlockState, world: World, pos: BlockPos, prevState: BlockState, moved: Boolean): Unit = { + if (!world.isClientSide) { + world.asInstanceOf[ServerWorld].getBlockTicks.scheduleTick(pos, this, Math.max((Settings.get.moveDelay * 20).toInt, 1) - 1) + } } - override def updateTick(world: World, pos: BlockPos, state: IBlockState, rand: Random) { - world.setBlockToAir(pos) + override def tick(state: BlockState, world: ServerWorld, pos: BlockPos, rand: Random) { + world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState) } - override def removedByPlayer(state: IBlockState, world: World, pos: BlockPos, player: EntityPlayer, willHarvest: Boolean): Boolean = { + override def removedByPlayer(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, willHarvest: Boolean, fluid: FluidState): Boolean = { findMovingRobot(world, pos) match { case Some(robot) if robot.isAnimatingMove && robot.moveFrom.contains(pos) => - robot.proxy.getBlockType.removedByPlayer(state, world, pos, player, false) - case _ => super.removedByPlayer(state, world, pos, player, willHarvest) // Probably broken by the robot we represent. + robot.proxy.getBlockState.getBlock.removedByPlayer(state, world, pos, player, false, fluid) + case _ => super.removedByPlayer(state, world, pos, player, willHarvest, fluid) // Probably broken by the robot we represent. } } - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = { + @Deprecated + override def use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, trace: BlockRayTraceResult): ActionResultType = { findMovingRobot(world, pos) match { - case Some(robot) => api.Items.get(Constants.BlockName.Robot).block.onBlockActivated(world, robot.getPos, world.getBlockState(robot.getPos), player, hand, side, hitX, hitY, hitZ) - case _ => world.setBlockToAir(pos) + case Some(robot) => api.Items.get(Constants.BlockName.Robot).block.use(world.getBlockState(robot.getBlockPos), world, robot.getBlockPos, player, hand, trace) + case _ => if (world.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState)) ActionResultType.sidedSuccess(world.isClientSide) else ActionResultType.PASS } } - def findMovingRobot(world: IBlockAccess, pos: BlockPos): Option[tileentity.Robot] = { - for (side <- EnumFacing.values) { - val tpos = pos.offset(side) + def findMovingRobot(world: IBlockReader, pos: BlockPos): Option[tileentity.Robot] = { + for (side <- Direction.values) { + val tpos = pos.relative(side) if (world match { - case world: World => world.isBlockLoaded(tpos) + case world: World => world.isLoaded(tpos) case _ => true - }) world.getTileEntity(tpos) match { + }) world.getBlockEntity(tpos) match { case proxy: tileentity.RobotProxy if proxy.robot.moveFrom.contains(pos) => return Some(proxy.robot) case _ => } diff --git a/src/main/scala/li/cil/oc/common/block/RobotProxy.scala b/src/main/scala/li/cil/oc/common/block/RobotProxy.scala index 437b13dc45..af4c8bb981 100644 --- a/src/main/scala/li/cil/oc/common/block/RobotProxy.scala +++ b/src/main/scala/li/cil/oc/common/block/RobotProxy.scala @@ -3,41 +3,46 @@ package li.cil.oc.common.block import java.util import li.cil.oc.Constants -import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.client.KeyBindings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.tileentity -import li.cil.oc.integration.util.ItemBlacklist import li.cil.oc.server.PacketSender import li.cil.oc.server.agent +import li.cil.oc.server.loot.LootFunctions import li.cil.oc.util.BlockPosition import li.cil.oc.util.InventoryUtils -import li.cil.oc.util.Rarity import li.cil.oc.util.Tooltip -import net.minecraft.block.state.IBlockState +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumRarity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.fluid.FluidState import net.minecraft.item.ItemStack -import net.minecraft.util._ -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.loot.LootContext +import net.minecraft.loot.LootParameters +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.util.math.RayTraceResult -import net.minecraft.util.math.Vec3d -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.math.shapes.VoxelShapes +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class RobotProxy extends RedstoneAware with traits.StateAware { - setLightOpacity(0) - setCreativeTab(null) - ItemBlacklist.hide(this) +import scala.collection.convert.ImplicitConversionsToScala._ - override val getUnlocalizedName = "robot" +class RobotProxy(props: Properties) extends RedstoneAware(props) with traits.StateAware { + val shape = VoxelShapes.box(0.1, 0.1, 0.1, 0.9, 0.9, 0.9) + + override val getDescriptionId = "robot" var moving = new ThreadLocal[Option[tileentity.Robot]] { override protected def initialValue = None @@ -45,82 +50,74 @@ class RobotProxy extends RedstoneAware with traits.StateAware { // ----------------------------------------------------------------------- // - override def isOpaqueCube(state: IBlockState): Boolean = false - - override def isFullCube(state: IBlockState): Boolean = false - - override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false - - override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false - - override def getPickBlock(state: IBlockState, target: RayTraceResult, world: World, pos: BlockPos, player: EntityPlayer): ItemStack = - world.getTileEntity(pos) match { + override def getPickBlock(state: BlockState, target: RayTraceResult, world: IBlockReader, pos: BlockPos, player: PlayerEntity): ItemStack = + world.getBlockEntity(pos) match { case proxy: tileentity.RobotProxy => proxy.robot.info.copyItemStack() case _ => ItemStack.EMPTY } - override def getBoundingBox(state: IBlockState, world: IBlockAccess, pos: BlockPos): AxisAlignedBB = { - world.getTileEntity(pos) match { + override def getShape(state: BlockState, world: IBlockReader, pos: BlockPos, ctx: ISelectionContext): VoxelShape = { + world.getBlockEntity(pos) match { case proxy: tileentity.RobotProxy => val robot = proxy.robot - val bounds = new AxisAlignedBB(0.1, 0.1, 0.1, 0.9, 0.9, 0.9) if (robot.isAnimatingMove) { val remaining = robot.animationTicksLeft.toDouble / robot.animationTicksTotal.toDouble val blockPos = robot.moveFrom.get - val vec = robot.getPos + val vec = robot.getBlockPos val delta = new BlockPos(blockPos.getX - vec.getX, blockPos.getY - vec.getY, blockPos.getZ - vec.getZ) - bounds.offset(delta.getX * remaining, delta.getY * remaining, delta.getZ * remaining) + shape.move(delta.getX * remaining, delta.getY * remaining, delta.getZ * remaining) } - else bounds - case _ => super.getBoundingBox(state, world, pos) + else shape + case _ => super.getShape(state, world, pos, ctx) } } // ----------------------------------------------------------------------- // - override def rarity(stack: ItemStack): EnumRarity = { - val data = new RobotData(stack) - Rarity.byTier(data.tier) - } - - override protected def tooltipHead(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - super.tooltipHead(metadata, stack, world, tooltip, advanced) + override protected def tooltipHead(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + super.tooltipHead(stack, world, tooltip, advanced) addLines(stack, tooltip) } - override protected def tooltipBody(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - tooltip.addAll(Tooltip.get("robot")) + override protected def tooltipBody(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + for (curr <- Tooltip.get("robot")) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - super.tooltipTail(metadata, stack, world, tooltip, flag) + override protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.tooltipTail(stack, world, tooltip, flag) if (KeyBindings.showExtendedTooltips) { val info = new RobotData(stack) val components = info.containers ++ info.components if (components.length > 0) { - tooltip.addAll(Tooltip.get("server.Components")) + for (curr <- Tooltip.get("server.Components")) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } for (component <- components if !component.isEmpty) { - tooltip.add("- " + component.getDisplayName) + tooltip.add(new StringTextComponent("- " + component.getHoverName.getString).setStyle(Tooltip.DefaultStyle)) } } } } - private def addLines(stack: ItemStack, tooltip: util.List[String]) { - if (stack.hasTagCompound) { - if (stack.getTagCompound.hasKey(Settings.namespace + "xp")) { - val xp = stack.getTagCompound.getDouble(Settings.namespace + "xp") + private def addLines(stack: ItemStack, tooltip: util.List[ITextComponent]) { + if (stack.hasTag) { + if (stack.getTag.contains(Settings.namespace + "xp")) { + val xp = stack.getTag.getDouble(Settings.namespace + "xp") val level = Math.min((Math.pow(xp - Settings.get.baseXpToLevel, 1 / Settings.get.exponentialXpGrowth) / Settings.get.constantXpGrowth).toInt, 30) if (level > 0) { - tooltip.addAll(Tooltip.get(getUnlocalizedName + "_level", level)) + for (curr <- Tooltip.get(getDescriptionId + "_level", level)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } } - if (stack.getTagCompound.hasKey(Settings.namespace + "storedEnergy")) { - val energy = stack.getTagCompound.getInteger(Settings.namespace + "storedEnergy") + if (stack.getTag.contains(Settings.namespace + "storedEnergy")) { + val energy = stack.getTag.getInt(Settings.namespace + "storedEnergy") if (energy > 0) { - tooltip.addAll(Tooltip.get(getUnlocalizedName + "_storedenergy", energy)) + for (curr <- Tooltip.get(getDescriptionId + "_storedenergy", energy)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } } } @@ -128,20 +125,16 @@ class RobotProxy extends RedstoneAware with traits.StateAware { // ----------------------------------------------------------------------- // - override def createNewTileEntity(world: World, metadata: Int): tileentity.RobotProxy = { + override def newBlockEntity(world: IBlockReader): tileentity.RobotProxy = { moving.get match { - case Some(robot) => new tileentity.RobotProxy(robot) - case _ => new tileentity.RobotProxy() + case Some(robot) => new tileentity.RobotProxy(tileentity.TileEntityTypes.ROBOT, robot) + case _ => new tileentity.RobotProxy(tileentity.TileEntityTypes.ROBOT) } } // ----------------------------------------------------------------------- // - override def getExplosionResistance(entity: Entity) = 10f - - override def getDrops(world: IBlockAccess, pos: BlockPos, state: IBlockState, fortune: Int): util.ArrayList[ItemStack] = { - val list = new java.util.ArrayList[ItemStack]() - + override def getDrops(state: BlockState, ctx: LootContext.Builder): util.List[ItemStack] = { // Superspecial hack... usually this will not work, because Minecraft calls // this method *after* the block has already been destroyed. Meaning we // won't have access to the tile entity. @@ -153,24 +146,26 @@ class RobotProxy extends RedstoneAware with traits.StateAware { // mod calls this before the block is broken *and* calls removedByPlayer // this will lead to dupes, but in some initial testing this wasn't the // case anywhere (TE autonomous activator, CC turtles). - world.getTileEntity(pos) match { - case proxy: tileentity.RobotProxy => - val robot = proxy.robot - if (robot.node != null) { - // Update: even more special hack! As discussed here http://git.io/IcNAyg - // some mods call this even when they're not about to actually break the - // block... soooo we need a whitelist to know when to generate a *proper* - // drop (i.e. with file systems closed / open handles not saved, e.g.). - if (gettingDropsForActualDrop) { - robot.node.remove() - robot.saveComponents() + val newCtx = ctx.withDynamicDrop(LootFunctions.DYN_ITEM_DATA, (c, f) => { + c.getParamOrNull(LootParameters.BLOCK_ENTITY) match { + case proxy: tileentity.RobotProxy => + val robot = proxy.robot + if (robot.node != null) { + // Update: even more special hack! As discussed here http://git.io/IcNAyg + // some mods call this even when they're not about to actually break the + // block... soooo we need a whitelist to know when to generate a *proper* + // drop (i.e. with file systems closed / open handles not saved, e.g.). + if (gettingDropsForActualDrop) { + robot.node.remove() + robot.saveComponents() + } + f.accept(robot.info.createItemStack()) } - list.add(robot.info.createItemStack()) - } - case _ => - } + case _ => + } + }) - list + super.getDrops(state, newCtx) } private val getDropForRealDropCallers = Set( @@ -179,35 +174,29 @@ class RobotProxy extends RedstoneAware with traits.StateAware { private def gettingDropsForActualDrop = new Exception().getStackTrace.exists(element => getDropForRealDropCallers.contains(element.getClassName + "." + element.getMethodName)) - override def collisionRayTrace(state: IBlockState, world: World, pos: BlockPos, start: Vec3d, end: Vec3d): RayTraceResult = { - val bounds = getCollisionBoundingBox(state, world, pos) - world.getTileEntity(pos) match { - case proxy: tileentity.RobotProxy if proxy.robot.animationTicksLeft <= 0 && bounds.contains(start) => null - case _ => super.collisionRayTrace(state, world, pos, start, end) - } - } - // ----------------------------------------------------------------------- // - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - if (!player.isSneaking) { - if (!world.isRemote) { + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + if (!player.isCrouching) { + if (!world.isClientSide) { // We only send slot changes to nearby players, so if there was no slot // change since this player got into range he might have the wrong one, // so we send him the current one just in case. - world.getTileEntity(pos) match { - case proxy: tileentity.RobotProxy if proxy.robot.node.network != null => + (player, world.getBlockEntity(pos)) match { + case (srvPlr: ServerPlayerEntity, proxy: tileentity.RobotProxy) if proxy.robot.node.network != null => PacketSender.sendRobotSelectedSlotChange(proxy.robot) - player.openGui(OpenComputers, GuiType.Robot.id, world, pos.getX, pos.getY, pos.getZ) + if (proxy.stillValid(player)) { + ContainerTypes.openRobotGui(srvPlr, proxy.robot) + } case _ => } } true } else if (heldItem.isEmpty) { - if (!world.isRemote) { - world.getTileEntity(pos) match { - case proxy: tileentity.RobotProxy if !proxy.machine.isRunning && proxy.isUsableByPlayer(player) => proxy.machine.start() + if (!world.isClientSide) { + world.getBlockEntity(pos) match { + case proxy: tileentity.RobotProxy if !proxy.machine.isRunning && proxy.stillValid(player) => proxy.machine.start() case _ => } } @@ -216,49 +205,45 @@ class RobotProxy extends RedstoneAware with traits.StateAware { else false } - override def onBlockPlacedBy(world: World, pos: BlockPos, state: IBlockState, entity: EntityLivingBase, stack: ItemStack) { - super.onBlockPlacedBy(world, pos, state, entity, stack) - if (!world.isRemote) ((entity, world.getTileEntity(pos)) match { + override def setPlacedBy(world: World, pos: BlockPos, state: BlockState, entity: LivingEntity, stack: ItemStack) { + super.setPlacedBy(world, pos, state, entity, stack) + if (!world.isClientSide) ((entity, world.getBlockEntity(pos)) match { case (player: agent.Player, proxy: tileentity.RobotProxy) => Some((proxy.robot, player.agent.ownerName, player.agent.ownerUUID)) - case (player: EntityPlayer, proxy: tileentity.RobotProxy) => - Some((proxy.robot, player.getName, player.getGameProfile.getId)) + case (player: PlayerEntity, proxy: tileentity.RobotProxy) => + Some((proxy.robot, player.getName.getString, player.getGameProfile.getId)) case _ => None }) match { case Some((robot, owner, uuid)) => robot.ownerName = owner robot.ownerUUID = agent.Player.determineUUID(Option(uuid)) - robot.info.load(stack) + robot.info.loadData(stack) robot.bot.node.changeBuffer(robot.info.robotEnergy - robot.bot.node.localBuffer) robot.updateInventorySize() case _ => } } - override def removedByPlayer(state: IBlockState, world: World, pos: BlockPos, player: EntityPlayer, willHarvest: Boolean): Boolean = { - world.getTileEntity(pos) match { + override def removedByPlayer(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, willHarvest: Boolean, fluid: FluidState): Boolean = { + world.getBlockEntity(pos) match { case proxy: tileentity.RobotProxy => val robot = proxy.robot // Only allow breaking creative tier robots by allowed users. // Unlike normal robots, griefing isn't really a valid concern // here, because to get a creative robot you need creative // mode in the first place. - if (robot.isCreative && (!player.capabilities.isCreativeMode || !robot.canInteract(player.getName))) return false - if (!world.isRemote) { + if (robot.isCreative && (!player.isCreative || !robot.canInteract(player.getName.getString))) return false + if (!world.isClientSide) { if (robot.player == player) return false robot.node.remove() robot.saveComponents() - InventoryUtils.spawnStackInWorld(BlockPosition(pos, world), robot.info.createItemStack()) + if (player.isCreative) InventoryUtils.spawnStackInWorld(BlockPosition(pos, world), robot.info.createItemStack()) } robot.moveFrom.foreach(fromPos => if (world.getBlockState(fromPos).getBlock == api.Items.get(Constants.BlockName.RobotAfterimage).block) { - world.setBlockState(fromPos, net.minecraft.init.Blocks.AIR.getDefaultState, 1) + world.setBlock(fromPos, net.minecraft.block.Blocks.AIR.defaultBlockState, 1) }) case _ => } - super.removedByPlayer(state, world, pos, player, willHarvest) + super.removedByPlayer(state, world, pos, player, willHarvest, fluid) } - - override def breakBlock(world: World, pos: BlockPos, state: IBlockState): Unit = - if (moving.get.isEmpty) - super.breakBlock(world, pos, state) } diff --git a/src/main/scala/li/cil/oc/common/block/Screen.scala b/src/main/scala/li/cil/oc/common/block/Screen.scala index 83b29c46f1..b2fde6fb1d 100644 --- a/src/main/scala/li/cil/oc/common/block/Screen.scala +++ b/src/main/scala/li/cil/oc/common/block/Screen.scala @@ -2,94 +2,81 @@ package li.cil.oc.common.block import java.util -import _root_.net.minecraft.entity.Entity -import _root_.net.minecraft.entity.EntityLivingBase -import _root_.net.minecraft.entity.player.EntityPlayer -import _root_.net.minecraft.entity.projectile.EntityArrow -import _root_.net.minecraft.item.ItemStack -import _root_.net.minecraft.util.EnumFacing -import _root_.net.minecraft.util.EnumHand -import _root_.net.minecraft.world.{IBlockAccess, World} -import _root_.net.minecraftforge.common.property.ExtendedBlockState -import _root_.net.minecraftforge.common.property.IExtendedBlockState import li.cil.oc.Constants import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api -import li.cil.oc.common.GuiType +import li.cil.oc.client.gui import li.cil.oc.common.block.property.PropertyRotatable -import li.cil.oc.common.block.property.PropertyTile import li.cil.oc.common.tileentity import li.cil.oc.integration.util.Wrench import li.cil.oc.util.PackedColor -import li.cil.oc.util.Rarity +import li.cil.oc.util.RotationHelper import li.cil.oc.util.Tooltip -import net.minecraft.block.state.IBlockState +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Block +import net.minecraft.block.BlockState import net.minecraft.client.Minecraft import net.minecraft.client.util.ITooltipFlag -import net.minecraft.util.math.{AxisAlignedBB, BlockPos} -import net.minecraftforge.fml.relauncher.{Side, SideOnly} - -class Screen(val tier: Int) extends RedstoneAware { - override def createBlockState() = new ExtendedBlockState(this, Array(PropertyRotatable.Pitch, PropertyRotatable.Yaw), Array(PropertyTile.Tile)) - - override def getMetaFromState(state: IBlockState): Int = (state.getValue(PropertyRotatable.Pitch).ordinal() << 2) | state.getValue(PropertyRotatable.Yaw).getHorizontalIndex - - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Pitch, EnumFacing.getFront(meta >> 2)).withProperty(PropertyRotatable.Yaw, EnumFacing.getHorizontal(meta & 0x3)) - - override def getExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos): IBlockState = - (state, world.getTileEntity(pos)) match { - case (extendedState: IExtendedBlockState, tile: tileentity.Screen) => - extendedState. - withProperty(property.PropertyTile.Tile, tile). - withProperty(PropertyRotatable.Pitch, tile.pitch). - withProperty(PropertyRotatable.Yaw, tile.yaw) - case _ => state - } - - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing) = toLocal(world, pos, side) != EnumFacing.SOUTH +import net.minecraft.entity.Entity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.projectile.ArrowEntity +import net.minecraft.item.ItemStack +import net.minecraft.state.StateContainer +import net.minecraft.util.Direction +import net.minecraft.util.Hand +import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.{IBlockReader, World} +import net.minecraftforge.api.distmarker.{Dist, OnlyIn} + +import scala.collection.convert.ImplicitConversionsToScala._ + +class Screen(props: Properties, val tier: Int) extends RedstoneAware(props) { + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Pitch, PropertyRotatable.Yaw) // ----------------------------------------------------------------------- // - override def rarity(stack: ItemStack) = Rarity.byTier(tier) - - override protected def tooltipBody(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { + override protected def tooltipBody(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { val (w, h) = Settings.screenResolutionsByTier(tier) val depth = PackedColor.Depth.bits(Settings.screenDepthsByTier(tier)) - tooltip.addAll(Tooltip.get(getClass.getSimpleName.toLowerCase, w, h, depth)) + for (curr <- Tooltip.get(getClass.getSimpleName.toLowerCase, w, h, depth)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } // ----------------------------------------------------------------------- // - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Screen(tier) + override def newBlockEntity(world: IBlockReader) = new tileentity.Screen(tileentity.TileEntityTypes.SCREEN, tier) // ----------------------------------------------------------------------- // - override def onBlockPlacedBy(world: World, pos: BlockPos, state: IBlockState, placer: EntityLivingBase, stack: ItemStack) { - super.onBlockPlacedBy(world, pos, state, placer, stack) - world.getTileEntity(pos) match { + override def setPlacedBy(world: World, pos: BlockPos, state: BlockState, placer: LivingEntity, stack: ItemStack) { + super.setPlacedBy(world, pos, state, placer, stack) + world.getBlockEntity(pos) match { case screen: tileentity.Screen => screen.delayUntilCheckForMultiBlock = 0 case _ => } } - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = rightClick(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ, force = false) + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = rightClick(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ, force = false) - def rightClick(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, - side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float, force: Boolean) = { + def rightClick(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, + side: Direction, hitX: Float, hitY: Float, hitZ: Float, force: Boolean) = { if (Wrench.holdsApplicableWrench(player, pos) && getValidRotations(world, pos).contains(side) && !force) false else if (api.Items.get(heldItem) == api.Items.get(Constants.ItemName.Analyzer)) false - else world.getTileEntity(pos) match { - case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isSneaking == screen.origin.invertTouchMode) => - // Yep, this GUI is actually purely client side. We could skip this - // if, but it is clearer this way (to trigger it from the server we - // would have to give screens a "container", which we do not want). - if (world.isRemote) { - player.openGui(OpenComputers, GuiType.Screen.id, world, pos.getX, pos.getY, pos.getZ) - } + else world.getBlockEntity(pos) match { + case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isCrouching == screen.origin.invertTouchMode) => + // Yep, this GUI is actually purely client side (to trigger it from + // the server we would have to give screens a "container", which we + // do not want). + if (world.isClientSide) showGui(screen) true case screen: tileentity.Screen if screen.tier > 0 && side == screen.facing => - if (world.isRemote && player == Minecraft.getMinecraft.player) { + if (world.isClientSide && player == Minecraft.getInstance.player) { screen.click(hitX, hitY, hitZ) } else true @@ -97,32 +84,37 @@ class Screen(val tier: Int) extends RedstoneAware { } } - override def onEntityWalk(world: World, pos: BlockPos, entity: Entity): Unit = - if (!world.isRemote) world.getTileEntity(pos) match { - case screen: tileentity.Screen if screen.tier > 0 && screen.facing == EnumFacing.UP => screen.walk(entity) - case _ => super.onEntityWalk(world, pos, entity) + @OnlyIn(Dist.CLIENT) + private def showGui(screen: tileentity.Screen) { + Minecraft.getInstance.pushGuiLayer(new gui.Screen(screen.origin.buffer, screen.tier > 0, () => screen.origin.hasKeyboard, () => screen.origin.buffer.isRenderingEnabled)) + } + + override def stepOn(world: World, pos: BlockPos, entity: Entity): Unit = + if (!world.isClientSide) world.getBlockEntity(pos) match { + case screen: tileentity.Screen if screen.tier > 0 && screen.facing == Direction.UP => screen.walk(entity) + case _ => super.stepOn(world, pos, entity) } - override def onEntityCollidedWithBlock(world: World, pos: BlockPos, state: IBlockState, entity: Entity): Unit = - if (world.isRemote) (entity, world.getTileEntity(pos)) match { - case (arrow: EntityArrow, screen: tileentity.Screen) if screen.tier > 0 => - val hitX = math.max(0, math.min(1, arrow.posX - pos.getX)) - val hitY = math.max(0, math.min(1, arrow.posY - pos.getY)) - val hitZ = math.max(0, math.min(1, arrow.posZ - pos.getZ)) + override def entityInside(state: BlockState, world: World, pos: BlockPos, entity: Entity): Unit = + if (world.isClientSide) (entity, world.getBlockEntity(pos)) match { + case (arrow: ArrowEntity, screen: tileentity.Screen) if screen.tier > 0 => + val hitX = math.max(0, math.min(1, arrow.getX - pos.getX)) + val hitY = math.max(0, math.min(1, arrow.getY - pos.getY)) + val hitZ = math.max(0, math.min(1, arrow.getZ - pos.getZ)) val absX = math.abs(hitX - 0.5) val absY = math.abs(hitY - 0.5) val absZ = math.abs(hitZ - 0.5) val side = if (absX > absY && absX > absZ) { - if (hitX < 0.5) EnumFacing.WEST - else EnumFacing.EAST + if (hitX < 0.5) Direction.WEST + else Direction.EAST } else if (absY > absZ) { - if (hitY < 0.5) EnumFacing.DOWN - else EnumFacing.UP + if (hitY < 0.5) Direction.DOWN + else Direction.UP } else { - if (hitZ < 0.5) EnumFacing.NORTH - else EnumFacing.SOUTH + if (hitZ < 0.5) Direction.NORTH + else Direction.SOUTH } if (side == screen.facing) { screen.shot(arrow) @@ -133,21 +125,12 @@ class Screen(val tier: Int) extends RedstoneAware { // ----------------------------------------------------------------------- // override def getValidRotations(world: World, pos: BlockPos) = - world.getTileEntity(pos) match { + world.getBlockEntity(pos) match { case screen: tileentity.Screen => - if (screen.facing == EnumFacing.UP || screen.facing == EnumFacing.DOWN) EnumFacing.values - else EnumFacing.values.filter { + if (screen.facing == Direction.UP || screen.facing == Direction.DOWN) Direction.values + else Direction.values.filter { d => d != screen.facing && d != screen.facing.getOpposite } case _ => super.getValidRotations(world, pos) } - - val emptyBB = new AxisAlignedBB(0, 0, 0, 0, 0, 0) - - @SideOnly(Side.CLIENT) - override def getSelectedBoundingBox(state: IBlockState, worldIn: World, pos: BlockPos): AxisAlignedBB = - if (!Minecraft.getMinecraft.player.isSneaking) - emptyBB - else - super.getSelectedBoundingBox(state, worldIn, pos) } diff --git a/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala b/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala index d187e662a7..21578aa098 100644 --- a/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala +++ b/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala @@ -7,108 +7,106 @@ import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity.traits.Colored import li.cil.oc.common.tileentity.traits.Inventory import li.cil.oc.common.tileentity.traits.Rotatable +import li.cil.oc.server.loot.LootFunctions import li.cil.oc.util.Color +import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.Tooltip -import net.minecraft.block.BlockContainer +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState +import net.minecraft.block.BlockRenderType +import net.minecraft.block.ContainerBlock import net.minecraft.block.material.Material -import net.minecraft.block.state.BlockFaceShape -import net.minecraft.block.state.IBlockState import net.minecraft.client.util.ITooltipFlag import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLiving.SpawnPlacementType -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumDyeColor -import net.minecraft.item.EnumRarity +import net.minecraft.entity.EntityType +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.DyeColor +import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack +import net.minecraft.loot.LootContext +import net.minecraft.loot.LootParameters import net.minecraft.tileentity.TileEntity -import net.minecraft.util._ +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.util.math.BlockRayTraceResult +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader +import net.minecraft.world.IWorldReader import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.common.ToolType -abstract class SimpleBlock(material: Material = Material.IRON) extends BlockContainer(material) { - setHardness(2f) - setResistance(5) - setCreativeTab(CreativeTab) +import scala.collection.convert.ImplicitConversionsToScala._ - var showInItemList = true +abstract class SimpleBlock(props: Properties) extends ContainerBlock(props) { + @Deprecated + private var unlocalizedName = super.getDescriptionId() - protected val validRotations_ = Array(EnumFacing.UP, EnumFacing.DOWN) + @Deprecated + private[oc] def setUnlocalizedName(name: String): Unit = unlocalizedName = "tile." + name - def createItemStack(amount: Int = 1) = new ItemStack(this, amount) + @Deprecated + override def getDescriptionId = unlocalizedName - override def createNewTileEntity(world: World, meta: Int): TileEntity = null - - @SideOnly(Side.CLIENT) - override def shouldSideBeRendered(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = { - val bounds = getBoundingBox(state, world, pos) - (side == EnumFacing.DOWN && bounds.minY > 0) || - (side == EnumFacing.UP && bounds.maxY < 1) || - (side == EnumFacing.NORTH && bounds.minZ > 0) || - (side == EnumFacing.SOUTH && bounds.maxZ < 1) || - (side == EnumFacing.WEST && bounds.minX > 0) || - (side == EnumFacing.EAST && bounds.maxX < 1) || - isOpaqueCube(state) - } + protected val validRotations_ = Array(Direction.UP, Direction.DOWN) - // ----------------------------------------------------------------------- // - // Rendering - // ----------------------------------------------------------------------- // + def createItemStack(amount: Int = 1) = new ItemStack(this, amount) - override def getRenderType(state: IBlockState): EnumBlockRenderType = EnumBlockRenderType.MODEL + override def newBlockEntity(world: IBlockReader): TileEntity = null - @SideOnly(Side.CLIENT) - def preItemRender(metadata: Int) {} + override def getRenderShape(state: BlockState): BlockRenderType = BlockRenderType.MODEL // ----------------------------------------------------------------------- // - // ItemBlock + // BlockItem // ----------------------------------------------------------------------- // - def rarity(stack: ItemStack) = EnumRarity.COMMON - - @SideOnly(Side.CLIENT) - def addInformation(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - tooltipHead(metadata, stack, world, tooltip, flag) - tooltipBody(metadata, stack, world, tooltip, flag) - tooltipTail(metadata, stack, world, tooltip, flag) + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + tooltipHead(stack, world, tooltip, flag) + tooltipBody(stack, world, tooltip, flag) + tooltipTail(stack, world, tooltip, flag) } - protected def tooltipHead(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { + protected def tooltipHead(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { } - protected def tooltipBody(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - tooltip.addAll(Tooltip.get(getClass.getSimpleName.toLowerCase)) + protected def tooltipBody(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + for (curr <- Tooltip.get(getClass.getSimpleName.toLowerCase)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } - protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { + protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { } // ----------------------------------------------------------------------- // // Rotation // ----------------------------------------------------------------------- // - def getFacing(world: IBlockAccess, pos: BlockPos): EnumFacing = - world.getTileEntity(pos) match { + def getFacing(world: IBlockReader, pos: BlockPos): Direction = + world.getBlockEntity(pos) match { case tileEntity: Rotatable => tileEntity.facing - case _ => EnumFacing.SOUTH + case _ => Direction.SOUTH } - def setFacing(world: World, pos: BlockPos, value: EnumFacing): Boolean = - world.getTileEntity(pos) match { + def setFacing(world: World, pos: BlockPos, value: Direction): Boolean = + world.getBlockEntity(pos) match { case rotatable: Rotatable => rotatable.setFromFacing(value); true case _ => false } def setRotationFromEntityPitchAndYaw(world: World, pos: BlockPos, value: Entity): Boolean = - world.getTileEntity(pos) match { + world.getBlockEntity(pos) match { case rotatable: Rotatable => rotatable.setFromEntityPitchAndYaw(value); true case _ => false } - def toLocal(world: IBlockAccess, pos: BlockPos, value: EnumFacing): EnumFacing = - world.getTileEntity(pos) match { + def toLocal(world: IBlockReader, pos: BlockPos, value: Direction): Direction = + world.getBlockEntity(pos) match { case rotatable: Rotatable => rotatable.toLocal(value) case _ => value } @@ -117,64 +115,69 @@ abstract class SimpleBlock(material: Material = Material.IRON) extends BlockCont // Block // ----------------------------------------------------------------------- // - override def getBlockFaceShape(world: IBlockAccess, state: IBlockState, pos: BlockPos, side: EnumFacing): BlockFaceShape = if(isBlockSolid(world, pos, side)) BlockFaceShape.SOLID else BlockFaceShape.UNDEFINED - - def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = world.getBlockState(pos).getMaterial.isSolid + override def canHarvestBlock(state: BlockState, world: IBlockReader, pos: BlockPos, player: PlayerEntity) = true - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = true + override def getHarvestTool(state: BlockState): ToolType = null - override def canHarvestBlock(world: IBlockAccess, pos: BlockPos, player: EntityPlayer) = true + override def canBeReplacedByLeaves(state: BlockState, world: IWorldReader, pos: BlockPos): Boolean = false - override def getHarvestTool(state: IBlockState): String = null + def getValidRotations(world: World, pos: BlockPos): Array[Direction] = validRotations_ - override def canBeReplacedByLeaves(state: IBlockState, world: IBlockAccess, pos: BlockPos): Boolean = false - - override def canCreatureSpawn(state: IBlockState, world: IBlockAccess, pos: BlockPos, `type`: SpawnPlacementType): Boolean = false - - override def getValidRotations(world: World, pos: BlockPos): Array[EnumFacing] = validRotations_ + override def getDrops(state: BlockState, ctx: LootContext.Builder): util.List[ItemStack] = { + val newCtx = ctx.getOptionalParameter(LootParameters.BLOCK_ENTITY) match { + case _: Inventory => ctx.withDynamicDrop(LootFunctions.DYN_VOLATILE_CONTENTS, (c, f) => { + c.getParamOrNull(LootParameters.BLOCK_ENTITY) match { + case inventory: Inventory => inventory.forAllLoot(f) + case _ => + } + }) + case _ => ctx + } + super.getDrops(state, newCtx) + } - override def breakBlock(world: World, pos: BlockPos, state: IBlockState): Unit = { - if (!world.isRemote) world.getTileEntity(pos) match { + override def playerWillDestroy(world: World, pos: BlockPos, state: BlockState, player: PlayerEntity) { + if (!world.isClientSide && player.isCreative) world.getBlockEntity(pos) match { case inventory: Inventory => inventory.dropAllSlots() case _ => // Ignore. } - super.breakBlock(world, pos, state) + super.playerWillDestroy(world, pos, state, player) } // ----------------------------------------------------------------------- // - override def rotateBlock(world: World, pos: BlockPos, axis: EnumFacing): Boolean = - world.getTileEntity(pos) match { + @Deprecated + def rotateBlock(world: World, pos: BlockPos, axis: Direction): Boolean = + world.getBlockEntity(pos) match { case rotatable: tileentity.traits.Rotatable if rotatable.rotate(axis) => - world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3) + world.sendBlockUpdated(pos, world.getBlockState(pos), world.getBlockState(pos), 3) true case _ => false } - override def recolorBlock(world: World, pos: BlockPos, side: EnumFacing, color: EnumDyeColor): Boolean = - world.getTileEntity(pos) match { - case colored: Colored if colored.getColor != Color.rgbValues(color) => - colored.setColor(Color.rgbValues(color)) - world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3) - true // Blame Vexatos. - case _ => super.recolorBlock(world, pos, side, color) - } - // ----------------------------------------------------------------------- // - override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, facing: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - val heldItem = player.getHeldItem(hand) - world.getTileEntity(pos) match { + override def use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, trace: BlockRayTraceResult): ActionResultType = { + val heldItem = player.getItemInHand(hand) + world.getBlockEntity(pos) match { case colored: Colored if Color.isDye(heldItem) => colored.setColor(Color.rgbValues(Color.dyeColor(heldItem))) - world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3) - if (!player.capabilities.isCreativeMode && colored.consumesDye) { - heldItem.splitStack(1) + world.sendBlockUpdated(pos, world.getBlockState(pos), world.getBlockState(pos), 3) + if (!player.isCreative && colored.consumesDye) { + heldItem.split(1) } - true - case _ => localOnBlockActivated(world, pos, player, hand, heldItem, facing, hitX, hitY, hitZ) + ActionResultType.sidedSuccess(world.isClientSide) + case _ => { + val loc = trace.getLocation + val pos = trace.getBlockPos + val x = loc.x.toFloat - pos.getX + val y = loc.y.toFloat - pos.getY + val z = loc.z.toFloat - pos.getZ + if (localOnBlockActivated(world, pos, player, hand, heldItem, trace.getDirection, x, y, z)) + ActionResultType.sidedSuccess(world.isClientSide) else ActionResultType.PASS + } } } - def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = false + def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = false } diff --git a/src/main/scala/li/cil/oc/common/block/Transposer.scala b/src/main/scala/li/cil/oc/common/block/Transposer.scala index 78f01d35e3..a54d894fb6 100644 --- a/src/main/scala/li/cil/oc/common/block/Transposer.scala +++ b/src/main/scala/li/cil/oc/common/block/Transposer.scala @@ -1,16 +1,13 @@ package li.cil.oc.common.block import li.cil.oc.common.tileentity -import net.minecraft.block.state.IBlockState -import net.minecraft.util.EnumFacing +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.BlockState +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IBlockReader import net.minecraft.world.World -class Transposer extends SimpleBlock { - override def isSideSolid(state: IBlockState, world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = false - - // ----------------------------------------------------------------------- // - - override def createNewTileEntity(world: World, meta: Int) = new tileentity.Transposer() +class Transposer(props: Properties) extends SimpleBlock(props) { + override def newBlockEntity(world: IBlockReader) = new tileentity.Transposer(tileentity.TileEntityTypes.TRANSPOSER) } diff --git a/src/main/scala/li/cil/oc/common/block/Waypoint.scala b/src/main/scala/li/cil/oc/common/block/Waypoint.scala index 8f6cbc5bab..294d2b0232 100644 --- a/src/main/scala/li/cil/oc/common/block/Waypoint.scala +++ b/src/main/scala/li/cil/oc/common/block/Waypoint.scala @@ -1,56 +1,54 @@ package li.cil.oc.common.block import li.cil.oc.OpenComputers -import li.cil.oc.common.GuiType -import li.cil.oc.common.block.property.{PropertyRotatable, PropertyTile} +import li.cil.oc.client.gui +import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.common.tileentity -import net.minecraft.block.state.BlockStateContainer -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import li.cil.oc.util.RotationHelper +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.Block +import net.minecraft.block.BlockState +import net.minecraft.client.Minecraft +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.state.StateContainer +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.world.{IBlockAccess, World} -import net.minecraftforge.common.property.{ExtendedBlockState, IExtendedBlockState} +import net.minecraft.util.math.BlockRayTraceResult +import net.minecraft.world.{IBlockReader, World} +import net.minecraftforge.api.distmarker.{Dist, OnlyIn} -class Waypoint extends RedstoneAware { - override def createBlockState() = new ExtendedBlockState(this, Array(PropertyRotatable.Pitch, PropertyRotatable.Yaw), Array(PropertyTile.Tile)) - - override def getMetaFromState(state: IBlockState): Int = (state.getValue(PropertyRotatable.Pitch).ordinal() << 2) | state.getValue(PropertyRotatable.Yaw).getHorizontalIndex - - override def getStateFromMeta(meta: Int): IBlockState = getDefaultState.withProperty(PropertyRotatable.Pitch, EnumFacing.getFront(meta >> 2)).withProperty(PropertyRotatable.Yaw, EnumFacing.getHorizontal(meta & 0x3)) - - override def getExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos): IBlockState = - (state, world.getTileEntity(pos)) match { - case (extendedState: IExtendedBlockState, tile: tileentity.Screen) => - extendedState. - withProperty(property.PropertyTile.Tile, tile). - withProperty(PropertyRotatable.Pitch, tile.pitch). - withProperty(PropertyRotatable.Yaw, tile.yaw) - case _ => state - } +class Waypoint(props: Properties) extends RedstoneAware(props) { + protected override def createBlockStateDefinition(builder: StateContainer.Builder[Block, BlockState]) = + builder.add(PropertyRotatable.Pitch, PropertyRotatable.Yaw) // ----------------------------------------------------------------------- // - override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Waypoint() + override def newBlockEntity(world: IBlockReader) = new tileentity.Waypoint(tileentity.TileEntityTypes.WAYPOINT) // ----------------------------------------------------------------------- // - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - if (!player.isSneaking) { - if (world.isRemote) { - player.openGui(OpenComputers, GuiType.Waypoint.id, world, pos.getX, pos.getY, pos.getZ) + override def use(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, trace: BlockRayTraceResult): ActionResultType = { + if (!player.isCrouching) { + if (world.isClientSide) world.getBlockEntity(pos) match { + case t: tileentity.Waypoint => showGui(t) + case _ => } - true + ActionResultType.sidedSuccess(world.isClientSide) } - else super.localOnBlockActivated(world, pos, player, hand, heldItem, side, hitX, hitY, hitZ) + else super.use(state, world, pos, player, hand, trace) + } + + @OnlyIn(Dist.CLIENT) + private def showGui(t: tileentity.Waypoint) { + Minecraft.getInstance.pushGuiLayer(new gui.Waypoint(t)) } - override def getValidRotations(world: World, pos: BlockPos): Array[EnumFacing] = - world.getTileEntity(pos) match { + override def getValidRotations(world: World, pos: BlockPos): Array[Direction] = + world.getBlockEntity(pos) match { case waypoint: tileentity.Waypoint => - EnumFacing.values.filter { + Direction.values.filter { d => d != waypoint.facing && d != waypoint.facing.getOpposite } case _ => super.getValidRotations(world, pos) diff --git a/src/main/scala/li/cil/oc/common/block/property/PropertyCableConnection.java b/src/main/scala/li/cil/oc/common/block/property/PropertyCableConnection.java new file mode 100644 index 0000000000..ce5917c306 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/block/property/PropertyCableConnection.java @@ -0,0 +1,54 @@ +package li.cil.oc.common.block.property; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.Map; + +import net.minecraft.state.EnumProperty; +import net.minecraft.util.Direction; +import net.minecraft.util.IStringSerializable; + +public final class PropertyCableConnection { + public static enum Shape implements IStringSerializable { + NONE("none"), + CABLE("cable"), + DEVICE("device"); + + private final String name; + + private Shape(String name) { + this.name = name; + } + + public String getSerializedName() { + return name; + } + + public String toString() { + return name; + } + } + + public static final EnumProperty DOWN = EnumProperty.create("conn_down", Shape.class); + public static final EnumProperty UP = EnumProperty.create("conn_up", Shape.class); + public static final EnumProperty NORTH = EnumProperty.create("conn_north", Shape.class); + public static final EnumProperty SOUTH = EnumProperty.create("conn_south", Shape.class); + public static final EnumProperty WEST = EnumProperty.create("conn_west", Shape.class); + public static final EnumProperty EAST = EnumProperty.create("conn_east", Shape.class); + public static Map> BY_DIRECTION; + + static + { + EnumMap> byDir = new EnumMap<>(Direction.class); + byDir.put(Direction.DOWN, DOWN); + byDir.put(Direction.UP, UP); + byDir.put(Direction.NORTH, NORTH); + byDir.put(Direction.SOUTH, SOUTH); + byDir.put(Direction.WEST, WEST); + byDir.put(Direction.EAST, EAST); + BY_DIRECTION = Collections.unmodifiableMap(byDir); + } + + private PropertyCableConnection() { + } +} diff --git a/src/main/scala/li/cil/oc/common/block/property/PropertyRotatable.scala b/src/main/scala/li/cil/oc/common/block/property/PropertyRotatable.scala index 930e337e46..569ee9c44d 100644 --- a/src/main/scala/li/cil/oc/common/block/property/PropertyRotatable.scala +++ b/src/main/scala/li/cil/oc/common/block/property/PropertyRotatable.scala @@ -1,14 +1,14 @@ package li.cil.oc.common.block.property -import com.google.common.base.Predicate -import com.google.common.base.Predicates -import net.minecraft.block.properties.PropertyDirection -import net.minecraft.util.EnumFacing +import java.util.function.Predicate -import scala.collection.convert.WrapAsJava._ +import net.minecraft.state.DirectionProperty +import net.minecraft.util.Direction + +import scala.collection.convert.ImplicitConversionsToJava._ object PropertyRotatable { - final val Facing = PropertyDirection.create("facing", EnumFacing.Plane.HORIZONTAL.asInstanceOf[Predicate[EnumFacing]]) - final val Pitch = PropertyDirection.create("pitch", Predicates.in(Set(EnumFacing.DOWN, EnumFacing.UP, EnumFacing.NORTH))) - final val Yaw = PropertyDirection.create("yaw", EnumFacing.Plane.HORIZONTAL.asInstanceOf[Predicate[EnumFacing]]) + final val Facing = DirectionProperty.create("facing", Direction.Plane.HORIZONTAL) + final val Pitch = DirectionProperty.create("pitch", d => d.getAxis == Direction.Axis.Y || d == Direction.NORTH) + final val Yaw = DirectionProperty.create("yaw", Direction.Plane.HORIZONTAL) } diff --git a/src/main/scala/li/cil/oc/common/block/property/PropertyRunning.scala b/src/main/scala/li/cil/oc/common/block/property/PropertyRunning.scala index f9ad0a7d2e..7aa3d7622f 100644 --- a/src/main/scala/li/cil/oc/common/block/property/PropertyRunning.scala +++ b/src/main/scala/li/cil/oc/common/block/property/PropertyRunning.scala @@ -1,7 +1,7 @@ package li.cil.oc.common.block.property -import net.minecraft.block.properties.PropertyBool +import net.minecraft.state.BooleanProperty object PropertyRunning { - final val Running = PropertyBool.create("running") + final val Running = BooleanProperty.create("running") } diff --git a/src/main/scala/li/cil/oc/common/block/property/PropertyTile.scala b/src/main/scala/li/cil/oc/common/block/property/PropertyTile.scala deleted file mode 100644 index c28a8cd095..0000000000 --- a/src/main/scala/li/cil/oc/common/block/property/PropertyTile.scala +++ /dev/null @@ -1,19 +0,0 @@ -package li.cil.oc.common.block.property - -import net.minecraft.tileentity.TileEntity -import net.minecraftforge.common.property.IUnlistedProperty - -object PropertyTile { - final val Tile = new PropertyTile() -} - -// Custom unlisted property used to pass a long tile entities to a block's renderer. -class PropertyTile extends IUnlistedProperty[TileEntity] { - override def getName = "tile" - - override def isValid(value: TileEntity) = true - - override def getType = classOf[TileEntity] - - override def valueToString(value: TileEntity) = value.toString -} diff --git a/src/main/scala/li/cil/oc/common/block/property/UnlistedInteger.scala b/src/main/scala/li/cil/oc/common/block/property/UnlistedInteger.scala deleted file mode 100644 index ed833c2ce4..0000000000 --- a/src/main/scala/li/cil/oc/common/block/property/UnlistedInteger.scala +++ /dev/null @@ -1,13 +0,0 @@ -package li.cil.oc.common.block.property - -import net.minecraftforge.common.property.IUnlistedProperty - -class UnlistedInteger(val name:String) extends IUnlistedProperty[Integer]{ - override def getName: String = name - - override def isValid(value: Integer): Boolean = value != null - - override def getType: Class[Integer] = classOf[Integer] - - override def valueToString(value: Integer): String = value.toString -} diff --git a/src/main/scala/li/cil/oc/common/block/traits/CustomDrops.scala b/src/main/scala/li/cil/oc/common/block/traits/CustomDrops.scala deleted file mode 100644 index f201ba1931..0000000000 --- a/src/main/scala/li/cil/oc/common/block/traits/CustomDrops.scala +++ /dev/null @@ -1,47 +0,0 @@ -package li.cil.oc.common.block.traits - -import java.util - -import li.cil.oc.common.block.SimpleBlock -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntity -import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess -import net.minecraft.world.World - -import scala.reflect.ClassTag - -trait CustomDrops[Tile <: TileEntity] extends SimpleBlock { - protected def tileTag: ClassTag[Tile] - - override def getDrops(world: IBlockAccess, pos: BlockPos, state: IBlockState, fortune: Int): util.List[ItemStack] = new java.util.ArrayList[ItemStack]() - - override def breakBlock(world: World, pos: BlockPos, state: IBlockState): Unit = {} - - override def removedByPlayer(state: IBlockState, world: World, pos: BlockPos, player: EntityPlayer, willHarvest: Boolean): Boolean = { - if (!world.isRemote) { - val matcher = tileTag - world.getTileEntity(pos) match { - case matcher(tileEntity) => doCustomDrops(tileEntity, player, willHarvest) - case _ => - } - } - super.removedByPlayer(state, world, pos, player, willHarvest) - } - - override def onBlockPlacedBy(world: World, pos: BlockPos, state: IBlockState, placer: EntityLivingBase, stack: ItemStack): Unit = { - super.onBlockPlacedBy(world, pos, state, placer, stack) - val matcher = tileTag - world.getTileEntity(pos) match { - case matcher(tileEntity) => doCustomInit(tileEntity, placer, stack) - case _ => - } - } - - protected def doCustomInit(tileEntity: Tile, player: EntityLivingBase, stack: ItemStack): Unit = {} - - protected def doCustomDrops(tileEntity: Tile, player: EntityPlayer, willHarvest: Boolean): Unit = {} -} diff --git a/src/main/scala/li/cil/oc/common/block/traits/GUI.scala b/src/main/scala/li/cil/oc/common/block/traits/GUI.scala index ac895350ab..e50324764e 100644 --- a/src/main/scala/li/cil/oc/common/block/traits/GUI.scala +++ b/src/main/scala/li/cil/oc/common/block/traits/GUI.scala @@ -1,22 +1,28 @@ package li.cil.oc.common.block.traits import li.cil.oc.OpenComputers -import li.cil.oc.common.GuiType import li.cil.oc.common.block.SimpleBlock -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.world.World trait GUI extends SimpleBlock { - def guiType: GuiType.EnumVal + def openGui(player: ServerPlayerEntity, world: World, pos: BlockPos) - override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - if (!player.isSneaking) { - if (!world.isRemote) { - player.openGui(OpenComputers, guiType.id, world, pos.getX, pos.getY, pos.getZ) + // This gets forwarded to the vanilla PlayerEntity.openMenu call which doesn't support extra data. + override def getMenuProvider(state: BlockState, world: World, pos: BlockPos): INamedContainerProvider = null + + override def localOnBlockActivated(world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, heldItem: ItemStack, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + if (!player.isCrouching) { + player match { + case srvPlr: ServerPlayerEntity if !world.isClientSide => openGui(srvPlr, world, pos) + case _ => } true } diff --git a/src/main/scala/li/cil/oc/common/block/traits/PowerAcceptor.scala b/src/main/scala/li/cil/oc/common/block/traits/PowerAcceptor.scala index a2ba010bf5..94180143d1 100644 --- a/src/main/scala/li/cil/oc/common/block/traits/PowerAcceptor.scala +++ b/src/main/scala/li/cil/oc/common/block/traits/PowerAcceptor.scala @@ -5,17 +5,23 @@ import java.util import li.cil.oc.common.block.SimpleBlock import li.cil.oc.util.Tooltip import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.world.World +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IBlockReader + +import scala.collection.convert.ImplicitConversionsToScala._ trait PowerAcceptor extends SimpleBlock { def energyThroughput: Double // ----------------------------------------------------------------------- // - override protected def tooltipTail(metadata: Int, stack: ItemStack, world: World, tooltip: util.List[String], advanced: ITooltipFlag) { - super.tooltipTail(metadata, stack, world, tooltip, advanced) - tooltip.addAll(Tooltip.extended("PowerAcceptor", energyThroughput.toInt)) + override protected def tooltipTail(stack: ItemStack, world: IBlockReader, tooltip: util.List[ITextComponent], advanced: ITooltipFlag) { + super.tooltipTail(stack, world, tooltip, advanced) + for (curr <- Tooltip.extended("poweracceptor", energyThroughput.toInt)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } } diff --git a/src/main/scala/li/cil/oc/common/block/traits/StateAware.scala b/src/main/scala/li/cil/oc/common/block/traits/StateAware.scala index a406f8760e..3ad68b5148 100644 --- a/src/main/scala/li/cil/oc/common/block/traits/StateAware.scala +++ b/src/main/scala/li/cil/oc/common/block/traits/StateAware.scala @@ -2,15 +2,15 @@ package li.cil.oc.common.block.traits import li.cil.oc.api import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.util.math.BlockPos import net.minecraft.world.World trait StateAware extends Block { - override def hasComparatorInputOverride(state: IBlockState): Boolean = true + override def hasAnalogOutputSignal(state: BlockState): Boolean = true - override def getComparatorInputOverride(state: IBlockState, world: World, pos: BlockPos): Int = - world.getTileEntity(pos) match { + override def getAnalogOutputSignal(state: BlockState, world: World, pos: BlockPos): Int = + world.getBlockEntity(pos) match { case stateful: api.util.StateAware => if (stateful.getCurrentState.contains(api.util.StateAware.State.IsWorking)) 15 else if (stateful.getCurrentState.contains(api.util.StateAware.State.CanWork)) 10 diff --git a/src/main/scala/li/cil/oc/common/capabilities/CapabilityColored.scala b/src/main/scala/li/cil/oc/common/capabilities/CapabilityColored.scala index b186caa6c3..f133a1a781 100644 --- a/src/main/scala/li/cil/oc/common/capabilities/CapabilityColored.scala +++ b/src/main/scala/li/cil/oc/common/capabilities/CapabilityColored.scala @@ -2,25 +2,29 @@ package li.cil.oc.common.capabilities import li.cil.oc.api.internal.Colored import li.cil.oc.integration.Mods -import net.minecraft.nbt.NBTBase -import net.minecraft.nbt.NBTTagInt +import net.minecraft.nbt.INBT +import net.minecraft.nbt.IntNBT import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier object CapabilityColored { final val ProviderColored = new ResourceLocation(Mods.IDs.OpenComputers, "colored") - class Provider(val tileEntity: TileEntity with Colored) extends ICapabilityProvider with Colored { - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { - capability == Capabilities.ColoredCapability - } + class Provider(val tileEntity: TileEntity with Colored) extends ICapabilityProvider with NonNullSupplier[Provider] with Colored { + private val wrapper = LazyOptional.of(this) + + def get = this + + def invalidate() = wrapper.invalidate - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { - if (hasCapability(capability, facing)) this.asInstanceOf[T] - else null.asInstanceOf[T] + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { + if (capability == Capabilities.ColoredCapability) wrapper.cast[T] + else LazyOptional.empty[T] } override def getColor = tileEntity.getColor @@ -41,15 +45,15 @@ object CapabilityColored { } class DefaultStorage extends Capability.IStorage[Colored] { - override def writeNBT(capability: Capability[Colored], t: Colored, enumFacing: EnumFacing): NBTBase = { + override def writeNBT(capability: Capability[Colored], t: Colored, Direction: Direction): INBT = { val color = t.getColor - new NBTTagInt(color) + IntNBT.valueOf(color) } - override def readNBT(capability: Capability[Colored], t: Colored, enumFacing: EnumFacing, nbtBase: NBTBase): Unit = { + override def readNBT(capability: Capability[Colored], t: Colored, Direction: Direction, nbtBase: INBT): Unit = { nbtBase match { - case nbt: NBTTagInt => - t.setColor(nbt.getInt) + case nbt: IntNBT => + t.setColor(nbt.getAsInt) case _ => } } diff --git a/src/main/scala/li/cil/oc/common/capabilities/CapabilityEnvironment.scala b/src/main/scala/li/cil/oc/common/capabilities/CapabilityEnvironment.scala index fe5ee5992b..19b321ef0f 100644 --- a/src/main/scala/li/cil/oc/common/capabilities/CapabilityEnvironment.scala +++ b/src/main/scala/li/cil/oc/common/capabilities/CapabilityEnvironment.scala @@ -6,25 +6,29 @@ import li.cil.oc.api.network.Message import li.cil.oc.api.network.Node import li.cil.oc.api.network.Visibility import li.cil.oc.integration.Mods -import net.minecraft.nbt.NBTBase -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.INBT +import net.minecraft.nbt.CompoundNBT import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier object CapabilityEnvironment { final val ProviderEnvironment = new ResourceLocation(Mods.IDs.OpenComputers, "environment") - class Provider(val tileEntity: TileEntity with Environment) extends ICapabilityProvider with Environment { - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { - capability == Capabilities.EnvironmentCapability - } + class Provider(val tileEntity: TileEntity with Environment) extends ICapabilityProvider with NonNullSupplier[Provider] with Environment { + private val wrapper = LazyOptional.of(this) + + def get = this + + def invalidate() = wrapper.invalidate - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { - if (hasCapability(capability, facing)) this.asInstanceOf[T] - else null.asInstanceOf[T] + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { + if (capability == Capabilities.EnvironmentCapability) wrapper.cast[T] + else LazyOptional.empty[T] } override def node = tileEntity.node @@ -47,21 +51,21 @@ object CapabilityEnvironment { } class DefaultStorage extends Capability.IStorage[Environment] { - override def writeNBT(capability: Capability[Environment], t: Environment, facing: EnumFacing): NBTBase = { + override def writeNBT(capability: Capability[Environment], t: Environment, facing: Direction): INBT = { val node = t.node if (node != null) { - val nbt = new NBTTagCompound() - node.save(nbt) + val nbt = new CompoundNBT() + node.saveData(nbt) nbt } else null } - override def readNBT(capability: Capability[Environment], t: Environment, facing: EnumFacing, nbtBase: NBTBase): Unit = { + override def readNBT(capability: Capability[Environment], t: Environment, facing: Direction, nbtBase: INBT): Unit = { nbtBase match { - case nbt: NBTTagCompound => + case nbt: CompoundNBT => val node = t.node - if (node != null) node.load(nbt) + if (node != null) node.loadData(nbt) case _ => } } diff --git a/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedComponent.scala b/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedComponent.scala index aecb4b2e39..c0fafb4485 100644 --- a/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedComponent.scala +++ b/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedComponent.scala @@ -5,27 +5,31 @@ import li.cil.oc.api.network.SidedComponent import li.cil.oc.api.network.SidedEnvironment import li.cil.oc.integration.Mods import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier object CapabilitySidedComponent { final val SidedComponent = new ResourceLocation(Mods.IDs.OpenComputers, "sided_component") - class Provider(val tileEntity: TileEntity with Environment with SidedComponent) extends ICapabilityProvider with SidedEnvironment { - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { - capability == Capabilities.SidedEnvironmentCapability - } + class Provider(val tileEntity: TileEntity with Environment with SidedComponent) extends ICapabilityProvider with NonNullSupplier[Provider] with SidedEnvironment { + private val wrapper = LazyOptional.of(this) + + def get = this + + def invalidate() = wrapper.invalidate - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { - if (hasCapability(capability, facing)) this.asInstanceOf[T] - else null.asInstanceOf[T] + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { + if (capability == Capabilities.SidedEnvironmentCapability) wrapper.cast[T] + else LazyOptional.empty[T] } - override def sidedNode(side: EnumFacing) = if (tileEntity.canConnectNode(side)) tileEntity.node else null + override def sidedNode(side: Direction) = if (tileEntity.canConnectNode(side)) tileEntity.node else null - override def canConnect(side: EnumFacing) = tileEntity.canConnectNode(side) + override def canConnect(side: Direction) = tileEntity.canConnectNode(side) } } diff --git a/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedEnvironment.scala b/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedEnvironment.scala index f2e619135c..4f42147374 100644 --- a/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedEnvironment.scala +++ b/src/main/scala/li/cil/oc/common/capabilities/CapabilitySidedEnvironment.scala @@ -3,41 +3,45 @@ package li.cil.oc.common.capabilities import li.cil.oc.api.network.Node import li.cil.oc.api.network.SidedEnvironment import li.cil.oc.integration.Mods -import net.minecraft.nbt.NBTBase +import net.minecraft.nbt.INBT import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier object CapabilitySidedEnvironment { final val ProviderSidedEnvironment = new ResourceLocation(Mods.IDs.OpenComputers, "sided_environment") - class Provider(val tileEntity: TileEntity with SidedEnvironment) extends ICapabilityProvider with SidedEnvironment { - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { - capability == Capabilities.SidedEnvironmentCapability - } + class Provider(val tileEntity: TileEntity with SidedEnvironment) extends ICapabilityProvider with NonNullSupplier[Provider] with SidedEnvironment { + private val wrapper = LazyOptional.of(this) + + def get = this + + def invalidate() = wrapper.invalidate - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { - if (hasCapability(capability, facing)) this.asInstanceOf[T] - else null.asInstanceOf[T] + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { + if (capability == Capabilities.SidedEnvironmentCapability) wrapper.cast[T] + else LazyOptional.empty[T] } - override def sidedNode(side: EnumFacing) = tileEntity.sidedNode(side) + override def sidedNode(side: Direction) = tileEntity.sidedNode(side) - override def canConnect(side: EnumFacing) = tileEntity.canConnect(side) + override def canConnect(side: Direction) = tileEntity.canConnect(side) } class DefaultImpl extends SidedEnvironment { - override def sidedNode(side: EnumFacing): Node = null + override def sidedNode(side: Direction): Node = null - override def canConnect(side: EnumFacing): Boolean = false + override def canConnect(side: Direction): Boolean = false } class DefaultStorage extends Capability.IStorage[SidedEnvironment] { - override def writeNBT(capability: Capability[SidedEnvironment], t: SidedEnvironment, enumFacing: EnumFacing): NBTBase = null + override def writeNBT(capability: Capability[SidedEnvironment], t: SidedEnvironment, Direction: Direction): INBT = null - override def readNBT(capability: Capability[SidedEnvironment], t: SidedEnvironment, enumFacing: EnumFacing, nbtBase: NBTBase): Unit = {} + override def readNBT(capability: Capability[SidedEnvironment], t: SidedEnvironment, Direction: Direction, nbtBase: INBT): Unit = {} } } diff --git a/src/main/scala/li/cil/oc/common/command/SimpleCommand.scala b/src/main/scala/li/cil/oc/common/command/SimpleCommand.scala deleted file mode 100644 index f36204e0de..0000000000 --- a/src/main/scala/li/cil/oc/common/command/SimpleCommand.scala +++ /dev/null @@ -1,23 +0,0 @@ -package li.cil.oc.common.command - -import java.util - -import net.minecraft.command.CommandBase -import net.minecraft.command.ICommandSender -import net.minecraft.server.MinecraftServer -import net.minecraftforge.fml.common.FMLCommonHandler - -import scala.collection.convert.WrapAsJava._ -import scala.collection.mutable - -abstract class SimpleCommand(val name: String) extends CommandBase { - protected var aliases = mutable.ListBuffer.empty[String] - - override def getName = name - - override def getAliases: util.List[String] = aliases - - override def checkPermission(server: MinecraftServer, sender: ICommandSender): Boolean = super.checkPermission(server, sender)|| (FMLCommonHandler.instance().getMinecraftServerInstance != null && FMLCommonHandler.instance().getMinecraftServerInstance.isSinglePlayer) - - override def isUsernameIndex(command: Array[String], i: Int) = false -} diff --git a/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala b/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala index 2d9f8f4dfe..570686029e 100644 --- a/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala @@ -3,12 +3,15 @@ package li.cil.oc.common.component import java.io.InvalidObjectException import java.security.InvalidParameterException +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.api.network.{Environment, Message, Node} -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT import li.cil.oc.api.internal.TextBuffer.ColorDepth import li.cil.oc.api import li.cil.oc.common.component.traits.{TextBufferProxy, VideoRamDevice, VideoRamRasterizer} +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn class GpuTextBuffer(val owner: String, val id: Int, val data: li.cil.oc.util.TextBuffer) extends traits.TextBufferProxy { @@ -30,14 +33,14 @@ class GpuTextBuffer(val owner: String, val id: Int, val data: li.cil.oc.util.Tex override def onBufferCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int): Unit = dirty = true override def onBufferFill(col: Int, row: Int, w: Int, h: Int, c: Char): Unit = dirty = true - override def load(nbt: NBTTagCompound): Unit = { + override def loadData(nbt: CompoundNBT): Unit = { // the data is initially dirty because other devices don't know about it yet - data.load(nbt) + data.loadData(nbt) dirty = true } - override def save(nbt: NBTTagCompound): Unit = { - data.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = { + data.saveData(nbt) dirty = false } @@ -52,18 +55,20 @@ class GpuTextBuffer(val owner: String, val id: Int, val data: li.cil.oc.util.Tex override def setViewport(width: Int, height: Int): Boolean = false override def setMaximumColorDepth(depth: ColorDepth): Unit = {} override def getMaximumColorDepth: ColorDepth = data.format.depth - override def renderText: Boolean = false + @OnlyIn(Dist.CLIENT) + override def renderText(stack: MatrixStack): Boolean = false override def renderWidth: Int = 0 override def renderHeight: Int = 0 override def setRenderingEnabled(enabled: Boolean): Unit = {} override def isRenderingEnabled: Boolean = false - override def keyDown(character: Char, code: Int, player: EntityPlayer): Unit = {} - override def keyUp(character: Char, code: Int, player: EntityPlayer): Unit = {} - override def clipboard(value: String, player: EntityPlayer): Unit = {} - override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = {} - override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = {} - override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = {} - override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer): Unit = {} + override def keyDown(character: Char, code: Int, player: PlayerEntity): Unit = {} + override def keyUp(character: Char, code: Int, player: PlayerEntity): Unit = {} + override def textInput(codePt: Int, player: PlayerEntity): Unit = {} + override def clipboard(value: String, player: PlayerEntity): Unit = {} + override def mouseDown(x: Double, y: Double, button: Int, player: PlayerEntity): Unit = {} + override def mouseDrag(x: Double, y: Double, button: Int, player: PlayerEntity): Unit = {} + override def mouseUp(x: Double, y: Double, button: Int, player: PlayerEntity): Unit = {} + override def mouseScroll(x: Double, y: Double, delta: Int, player: PlayerEntity): Unit = {} override def canUpdate: Boolean = false override def update(): Unit = {} override def onConnect(node: Node): Unit = {} @@ -91,7 +96,7 @@ object ClientGpuTextBufferHandler { } } - def loadBuffer(buffer: api.internal.TextBuffer, owner: String, id: Int, nbt: NBTTagCompound): Boolean = { + def loadBuffer(buffer: api.internal.TextBuffer, owner: String, id: Int, nbt: CompoundNBT): Boolean = { buffer match { case screen: VideoRamRasterizer => screen.loadBuffer(owner, id, nbt) case _ => false // ignore, not compatible with bitblts diff --git a/src/main/scala/li/cil/oc/common/component/TerminalServer.scala b/src/main/scala/li/cil/oc/common/component/TerminalServer.scala index 4832c5d136..61d1db1923 100644 --- a/src/main/scala/li/cil/oc/common/component/TerminalServer.scala +++ b/src/main/scala/li/cil/oc/common/component/TerminalServer.scala @@ -23,18 +23,17 @@ import li.cil.oc.api.util.StateAware import li.cil.oc.api.util.StateAware.State import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagString -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.StringNBT +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraftforge.common.util.Constants.NBT -import scala.collection.convert.WrapAsScala._ -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToScala._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environment with EnvironmentHost with Analyzable with RackMountable with Lifecycle with DeviceInfo { @@ -53,10 +52,10 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ val keyboardItem = api.Items.get(Constants.BlockName.Keyboard).createItemStack(1) val keyboard = api.Driver.driverFor(keyboardItem, getClass).createEnvironment(keyboardItem, this).asInstanceOf[api.internal.Keyboard] keyboard.setUsableOverride(new UsabilityChecker { - override def isUsableByPlayer(keyboard: api.internal.Keyboard, player: EntityPlayer) = { - val stack = player.getHeldItemMainhand - Delegator.subItem(stack) match { - case Some(t: item.Terminal) if stack.hasTagCompound => sidedKeys.contains(stack.getTagCompound.getString(Settings.namespace + "key")) + override def isUsableByPlayer(keyboard: api.internal.Keyboard, player: PlayerEntity) = { + val stack = player.getItemInHand(Hand.MAIN_HAND) + stack.getItem match { + case t: item.Terminal if stack.hasTag => sidedKeys.contains(stack.getTag.getString(Settings.namespace + "key")) case _ => false } } @@ -71,7 +70,7 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ if (rack != null) { val data = rack.getMountableData(slot) if (data != null) { - return data.hasKey("terminalAddress") + return data.contains("terminalAddress") } } false @@ -80,8 +79,8 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ def address: String = rack.getMountableData(slot).getString("terminalAddress") def sidedKeys = { - if (!rack.world.isRemote) keys - else rack.getMountableData(slot).getTagList("keys", NBT.TAG_STRING).map((tag: NBTTagString) => tag.getString) + if (!rack.world.isClientSide) keys + else rack.getMountableData(slot).getList("keys", NBT.TAG_STRING).map((tag: StringNBT) => tag.getAsString) } // ----------------------------------------------------------------------- // @@ -133,12 +132,12 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ // ----------------------------------------------------------------------- // // RackMountable - override def getData: NBTTagCompound = { + override def getData: CompoundNBT = { if (node.address == null) api.Network.joinNewNetwork(node) - val nbt = new NBTTagCompound() + val nbt = new CompoundNBT() nbt.setNewTagList("keys", keys) - nbt.setString("terminalAddress", node.address) + nbt.putString("terminalAddress", node.address) nbt } @@ -146,25 +145,20 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ override def getConnectableAt(index: Int): RackBusConnectable = null - override def onActivate(player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, hitX: Float, hitY: Float): Boolean = { + override def onActivate(player: PlayerEntity, hand: Hand, heldItem: ItemStack, hitX: Float, hitY: Float): Boolean = { if (api.Items.get(heldItem) == api.Items.get(Constants.ItemName.Terminal)) { - if (!world.isRemote) { + if (!world.isClientSide) { val key = UUID.randomUUID().toString - if (!heldItem.hasTagCompound) { - heldItem.setTagCompound(new NBTTagCompound()) - } - else { - keys -= heldItem.getTagCompound.getString(Settings.namespace + "key") - } + keys -= heldItem.getOrCreateTag.getString(Settings.namespace + "key") val maxSize = Settings.get.terminalsPerServer while (keys.length >= maxSize) { keys.remove(0) } keys += key - heldItem.getTagCompound.setString(Settings.namespace + "key", key) - heldItem.getTagCompound.setString(Settings.namespace + "server", node.address) + heldItem.getTag.putString(Settings.namespace + "key", key) + heldItem.getTag.putString(Settings.namespace + "server", node.address) rack.markChanged(slot) - player.inventory.markDirty() + player.inventory.setChanged() } true } @@ -178,20 +172,20 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ private final val KeyboardTag = Settings.namespace + "keyboard" private final val KeysTag = Settings.namespace + "keys" - override def load(nbt: NBTTagCompound): Unit = { - if (!rack.world.isRemote) { - node.load(nbt) + override def loadData(nbt: CompoundNBT): Unit = { + if (!rack.world.isClientSide) { + node.loadData(nbt) } - buffer.load(nbt.getCompoundTag(BufferTag)) - keyboard.load(nbt.getCompoundTag(KeyboardTag)) + buffer.loadData(nbt.getCompound(BufferTag)) + keyboard.loadData(nbt.getCompound(KeyboardTag)) keys.clear() - nbt.getTagList(KeysTag, NBT.TAG_STRING).foreach((tag: NBTTagString) => keys += tag.getString) + nbt.getList(KeysTag, NBT.TAG_STRING).foreach((tag: StringNBT) => keys += tag.getAsString) } - override def save(nbt: NBTTagCompound): Unit = { - node.save(nbt) - nbt.setNewCompoundTag(BufferTag, buffer.save) - nbt.setNewCompoundTag(KeyboardTag, keyboard.save) + override def saveData(nbt: CompoundNBT): Unit = { + node.saveData(nbt) + nbt.setNewCompoundTag(BufferTag, buffer.saveData) + nbt.setNewCompoundTag(KeyboardTag, keyboard.saveData) nbt.setNewTagList(KeysTag, keys) } @@ -201,7 +195,7 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ override def canUpdate: Boolean = true override def update(): Unit = { - if (world.isRemote || (node.address != null && node.network != null)) { + if (world.isClientSide || (node.address != null && node.network != null)) { buffer.update() } } @@ -216,12 +210,12 @@ class TerminalServer(val rack: api.internal.Rack, val slot: Int) extends Environ // ----------------------------------------------------------------------- // // Analyzable - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(buffer.node, keyboard.node) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(buffer.node, keyboard.node) // ----------------------------------------------------------------------- // // LifeCycle - override def onLifecycleStateChange(state: Lifecycle.LifecycleState): Unit = if (rack.world.isRemote) state match { + override def onLifecycleStateChange(state: Lifecycle.LifecycleState): Unit = if (rack.world.isClientSide) state match { case Lifecycle.LifecycleState.Initialized => TerminalServer.loaded.add(this) case Lifecycle.LifecycleState.Disposed => diff --git a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala index 51cb8c83d8..c780521b17 100644 --- a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.component import com.google.common.base.Strings +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.Constants import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute import li.cil.oc.api.driver.DeviceInfo.DeviceClass @@ -31,17 +32,17 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.PackedColor import li.cil.oc.util.SideTracker import net.minecraft.client.Minecraft -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumHand +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Hand import net.minecraftforge.event.world.ChunkEvent import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment with traits.TextBufferProxy with VideoRamRasterizer with DeviceInfo { @@ -125,7 +126,7 @@ class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment w override def update() { super.update() - if (isDisplaying && host.world.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (isDisplaying && host.world.getGameTime % Settings.get.tickFrequency == 0) { if (relativeLitArea < 0) { // The relative lit area is the number of pixels that are not blank // versus the number of pixels in the *current* resolution. This is @@ -220,7 +221,7 @@ class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment w precisionMode = args.checkBoolean(0) result(oldValue) } - else result(Unit, "unsupported operation") + else result((), "unsupported operation") } // ----------------------------------------------------------------------- // @@ -257,7 +258,7 @@ class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment w override def getMaximumHeight: Int = maxResolution._2 - override def setAspectRatio(width: Double, height: Double): Unit = this.synchronized(aspectRatio = (width, height)) + override def setAspectRatio(width: Double, height: Double): Unit = this.synchronized(this.aspectRatio = (width, height)) override def getAspectRatio: Double = aspectRatio._1 / aspectRatio._2 @@ -361,43 +362,46 @@ class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment w proxy.onBufferRawSetForeground(col, row, color) } - @SideOnly(Side.CLIENT) - override def renderText: Boolean = relativeLitArea != 0 && proxy.render() + @OnlyIn(Dist.CLIENT) + override def renderText(stack: MatrixStack): Boolean = relativeLitArea != 0 && proxy.render(stack) - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def renderWidth: Int = TextBufferRenderCache.renderer.charRenderWidth * getViewportWidth - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def renderHeight: Int = TextBufferRenderCache.renderer.charRenderHeight * getViewportHeight - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def setRenderingEnabled(enabled: Boolean): Unit = isRendering = enabled - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def isRenderingEnabled: Boolean = isRendering - override def keyDown(character: Char, code: Int, player: EntityPlayer): Unit = + override def keyDown(character: Char, code: Int, player: PlayerEntity): Unit = proxy.keyDown(character, code, player) - override def keyUp(character: Char, code: Int, player: EntityPlayer): Unit = + override def keyUp(character: Char, code: Int, player: PlayerEntity): Unit = proxy.keyUp(character, code, player) - override def clipboard(value: String, player: EntityPlayer): Unit = + override def textInput(codePt: Int, player: PlayerEntity): Unit = + proxy.textInput(codePt, player) + + override def clipboard(value: String, player: PlayerEntity): Unit = proxy.clipboard(value, player) - override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = + override def mouseDown(x: Double, y: Double, button: Int, player: PlayerEntity): Unit = proxy.mouseDown(x, y, button, player) - override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = + override def mouseDrag(x: Double, y: Double, button: Int, player: PlayerEntity): Unit = proxy.mouseDrag(x, y, button, player) - override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = + override def mouseUp(x: Double, y: Double, button: Int, player: PlayerEntity): Unit = proxy.mouseUp(x, y, button, player) - override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer): Unit = + override def mouseScroll(x: Double, y: Double, delta: Int, player: PlayerEntity): Unit = proxy.mouseScroll(x, y, delta, player) - def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = { + def copyToAnalyzer(line: Int, player: PlayerEntity): Unit = { proxy.copyToAnalyzer(line, player) } @@ -428,38 +432,38 @@ class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment w private final val ViewportWidthTag = Settings.namespace + "viewportWidth" private final val ViewportHeightTag = Settings.namespace + "viewportHeight" - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) if (SideTracker.isClient) { if (!Strings.isNullOrEmpty(proxy.nodeAddress)) return // Only load once. - proxy.nodeAddress = nbt.getCompoundTag(NodeData.NodeTag).getString(NodeData.AddressTag) + proxy.nodeAddress = nbt.getCompound(NodeData.NodeTag).getString(NodeData.AddressTag) TextBuffer.registerClientBuffer(this) } else { - if (nbt.hasKey(NodeData.BufferTag)) { - data.load(nbt.getCompoundTag(NodeData.BufferTag)) + if (nbt.contains(NodeData.BufferTag)) { + data.loadData(nbt.getCompound(NodeData.BufferTag)) } else if (!Strings.isNullOrEmpty(node.address)) { - data.load(SaveHandler.loadNBT(nbt, bufferPath)) + data.loadData(SaveHandler.loadNBT(nbt, bufferPath)) } } - if (nbt.hasKey(IsOnTag)) { + if (nbt.contains(IsOnTag)) { isDisplaying = nbt.getBoolean(IsOnTag) } - if (nbt.hasKey(HasPowerTag)) { + if (nbt.contains(HasPowerTag)) { hasPower = nbt.getBoolean(HasPowerTag) } - if (nbt.hasKey(MaxWidthTag) && nbt.hasKey(MaxHeightTag)) { - val maxWidth = nbt.getInteger(MaxWidthTag) - val maxHeight = nbt.getInteger(MaxHeightTag) + if (nbt.contains(MaxWidthTag) && nbt.contains(MaxHeightTag)) { + val maxWidth = nbt.getInt(MaxWidthTag) + val maxHeight = nbt.getInt(MaxHeightTag) maxResolution = (maxWidth, maxHeight) } precisionMode = nbt.getBoolean(PreciseTag) - if (nbt.hasKey(ViewportWidthTag)) { - val vpw = nbt.getInteger(ViewportWidthTag) - val vph = nbt.getInteger(ViewportHeightTag) + if (nbt.contains(ViewportWidthTag)) { + val vpw = nbt.getInt(ViewportWidthTag) + val vph = nbt.getInt(ViewportHeightTag) viewport = (vpw min data.width max 1, vph min data.height max 1) } else { viewport = data.size @@ -467,8 +471,8 @@ class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment w } // Null check for Waila (and other mods that may call this client side). - override def save(nbt: NBTTagCompound): Unit = if (node != null) { - super.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = if (node != null) { + super.saveData(nbt) // Happy thread synchronization hack! Here's the problem: GPUs allow direct // calls for modifying screens to give a more responsive experience. This // causes the following problem: when saving, if the screen is saved first, @@ -486,14 +490,14 @@ class TextBuffer(val host: EnvironmentHost) extends AbstractManagedEnvironment w } } - SaveHandler.scheduleSave(host, nbt, bufferPath, data.save _) - nbt.setBoolean(IsOnTag, isDisplaying) - nbt.setBoolean(HasPowerTag, hasPower) - nbt.setInteger(MaxWidthTag, maxResolution._1) - nbt.setInteger(MaxHeightTag, maxResolution._2) - nbt.setBoolean(PreciseTag, precisionMode) - nbt.setInteger(ViewportWidthTag, viewport._1) - nbt.setInteger(ViewportHeightTag, viewport._2) + SaveHandler.scheduleSave(host, nbt, bufferPath, data.saveData _) + nbt.putBoolean(IsOnTag, isDisplaying) + nbt.putBoolean(HasPowerTag, hasPower) + nbt.putInt(MaxWidthTag, maxResolution._1) + nbt.putInt(MaxHeightTag, maxResolution._2) + nbt.putBoolean(PreciseTag, precisionMode) + nbt.putInt(ViewportWidthTag, viewport._1) + nbt.putInt(ViewportHeightTag, viewport._2) } } @@ -501,11 +505,12 @@ object TextBuffer { var clientBuffers = mutable.ListBuffer.empty[TextBuffer] @SubscribeEvent - def onChunkUnload(e: ChunkEvent.Unload) { + def onChunkUnloaded(e: ChunkEvent.Unload) { val chunk = e.getChunk clientBuffers = clientBuffers.filter(t => { val blockPos = BlockPosition(t.host) - val keep = t.host.world != e.getWorld || !chunk.isAtLocation(blockPos.x >> 4, blockPos.z >> 4) + val chunkPos = chunk.getPos + val keep = t.host.world != e.getWorld || ((blockPos.x >> 4) != chunkPos.x || (blockPos.z >> 4) != chunkPos.z) if (!keep) { ClientComponentTracker.remove(t.host.world, t) } @@ -537,11 +542,12 @@ object TextBuffer { var nodeAddress = "" - def markDirty() { + def setChanged() { dirty = true } - def render() = false + @OnlyIn(Dist.CLIENT) + def render(stack: MatrixStack) = false def onBufferColorChange(): Unit @@ -596,21 +602,23 @@ object TextBuffer { owner.relativeLitArea = -1 } - def keyDown(character: Char, code: Int, player: EntityPlayer): Unit + def keyDown(character: Char, code: Int, player: PlayerEntity): Unit + + def keyUp(character: Char, code: Int, player: PlayerEntity): Unit - def keyUp(character: Char, code: Int, player: EntityPlayer): Unit + def textInput(codePt: Int, player: PlayerEntity): Unit - def clipboard(value: String, player: EntityPlayer): Unit + def clipboard(value: String, player: PlayerEntity): Unit - def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit + def mouseDown(x: Double, y: Double, button: Int, player: PlayerEntity): Unit - def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer): Unit + def mouseDrag(x: Double, y: Double, button: Int, player: PlayerEntity): Unit - def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit + def mouseUp(x: Double, y: Double, button: Int, player: PlayerEntity): Unit - def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer): Unit + def mouseScroll(x: Double, y: Double, delta: Int, player: PlayerEntity): Unit - def copyToAnalyzer(line: Int, player: EntityPlayer): Unit + def copyToAnalyzer(line: Int, player: PlayerEntity): Unit } class ClientProxy(val owner: TextBuffer) extends Proxy { @@ -624,52 +632,53 @@ object TextBuffer { override def viewport: (Int, Int) = owner.viewport } - override def render() = { + @OnlyIn(Dist.CLIENT) + override def render(stack: MatrixStack) = { val wasDirty = dirty - TextBufferRenderCache.render(renderer) + TextBufferRenderCache.render(stack, renderer) wasDirty } override def onBufferColorChange() { - markDirty() + setChanged() } override def onBufferCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) { super.onBufferCopy(col, row, w, h, tx, ty) - markDirty() + setChanged() } override def onBufferDepthChange(depth: api.internal.TextBuffer.ColorDepth) { - markDirty() + setChanged() } override def onBufferFill(col: Int, row: Int, w: Int, h: Int, c: Char) { super.onBufferFill(col, row, w, h, c) - markDirty() + setChanged() } override def onBufferPaletteChange(index: Int) { - markDirty() + setChanged() } override def onBufferResolutionChange(w: Int, h: Int) { super.onBufferResolutionChange(w, h) - markDirty() + setChanged() } override def onBufferViewportResolutionChange(w: Int, h: Int) { super.onBufferViewportResolutionChange(w, h) - markDirty() + setChanged() } override def onBufferSet(col: Int, row: Int, s: String, vertical: Boolean) { super.onBufferSet(col, row, s, vertical) - markDirty() + setChanged() } override def onBufferBitBlt(col: Int, row: Int, w: Int, h: Int, ram: component.GpuTextBuffer, fromCol: Int, fromRow: Int): Unit = { super.onBufferBitBlt(col, row, w, h, ram, fromCol, fromRow) - markDirty() + setChanged() } override def onBufferRamInit(ram: component.GpuTextBuffer): Unit = { @@ -680,49 +689,54 @@ object TextBuffer { super.onBufferRamDestroy(ram) } - override def keyDown(character: Char, code: Int, player: EntityPlayer) { + override def keyDown(character: Char, code: Int, player: PlayerEntity) { debug(s"{type = keyDown, char = $character, code = $code}") ClientPacketSender.sendKeyDown(nodeAddress, character, code) } - override def keyUp(character: Char, code: Int, player: EntityPlayer) { + override def keyUp(character: Char, code: Int, player: PlayerEntity) { debug(s"{type = keyUp, char = $character, code = $code}") ClientPacketSender.sendKeyUp(nodeAddress, character, code) } - override def clipboard(value: String, player: EntityPlayer) { + override def textInput(codePt: Int, player: PlayerEntity) { + debug(s"{type = textInput, codePt = $codePt}") + ClientPacketSender.sendTextInput(nodeAddress, codePt) + } + + override def clipboard(value: String, player: PlayerEntity) { debug(s"{type = clipboard}") ClientPacketSender.sendClipboard(nodeAddress, value) } - override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) { + override def mouseDown(x: Double, y: Double, button: Int, player: PlayerEntity) { debug(s"{type = mouseDown, x = $x, y = $y, button = $button}") ClientPacketSender.sendMouseClick(nodeAddress, x, y, drag = false, button) } - override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer) { + override def mouseDrag(x: Double, y: Double, button: Int, player: PlayerEntity) { debug(s"{type = mouseDrag, x = $x, y = $y, button = $button}") ClientPacketSender.sendMouseClick(nodeAddress, x, y, drag = true, button) } - override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer) { + override def mouseUp(x: Double, y: Double, button: Int, player: PlayerEntity) { debug(s"{type = mouseUp, x = $x, y = $y, button = $button}") ClientPacketSender.sendMouseUp(nodeAddress, x, y, button) } - override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer) { + override def mouseScroll(x: Double, y: Double, delta: Int, player: PlayerEntity) { debug(s"{type = mouseScroll, x = $x, y = $y, delta = $delta}") ClientPacketSender.sendMouseScroll(nodeAddress, x, y, delta) } - override def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = { + override def copyToAnalyzer(line: Int, player: PlayerEntity): Unit = { ClientPacketSender.sendCopyToAnalyzer(nodeAddress, line) } private lazy val Debugger = api.Items.get(Constants.ItemName.Debugger) private def debug(message: String) { - if (Minecraft.getMinecraft != null && Minecraft.getMinecraft.player != null && api.Items.get(Minecraft.getMinecraft.player.getHeldItemMainhand) == Debugger) { + if (Minecraft.getInstance != null && Minecraft.getInstance.player != null && api.Items.get(Minecraft.getInstance.player.getItemInHand(Hand.MAIN_HAND)) == Debugger) { OpenComputers.log.info(s"[NETWORK DEBUGGER] Sending packet to node $nodeAddress: " + message) } } @@ -791,8 +805,8 @@ object TextBuffer { override def onBufferRamInit(ram: component.GpuTextBuffer): Unit = { super.onBufferRamInit(ram) owner.host.markChanged() - val nbt = new NBTTagCompound() - ram.save(nbt) + val nbt = new CompoundNBT() + ram.saveData(nbt) owner.synchronized(ServerPacketSender.appendTextBufferRamInit(owner.pendingCommands, ram.owner, ram.id, nbt)) } @@ -820,56 +834,53 @@ object TextBuffer { owner.synchronized(ServerPacketSender.appendTextBufferRawSetForeground(owner.pendingCommands, col, row, color)) } - override def keyDown(character: Char, code: Int, player: EntityPlayer) { + override def keyDown(character: Char, code: Int, player: PlayerEntity) { sendToKeyboards("keyboard.keyDown", player, Char.box(character), Int.box(code)) } - override def keyUp(character: Char, code: Int, player: EntityPlayer) { + override def keyUp(character: Char, code: Int, player: PlayerEntity) { sendToKeyboards("keyboard.keyUp", player, Char.box(character), Int.box(code)) } - override def clipboard(value: String, player: EntityPlayer) { + override def textInput(codePt: Int, player: PlayerEntity) { + sendToKeyboards("keyboard.textInput", player, Int.box(codePt)) + } + + override def clipboard(value: String, player: PlayerEntity) { sendToKeyboards("keyboard.clipboard", player, value) } - override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) { + override def mouseDown(x: Double, y: Double, button: Int, player: PlayerEntity) { sendMouseEvent(player, "touch", x, y, button) } - override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer) { + override def mouseDrag(x: Double, y: Double, button: Int, player: PlayerEntity) { sendMouseEvent(player, "drag", x, y, button) } - override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer) { + override def mouseUp(x: Double, y: Double, button: Int, player: PlayerEntity) { sendMouseEvent(player, "drop", x, y, button) } - override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer) { + override def mouseScroll(x: Double, y: Double, delta: Int, player: PlayerEntity) { sendMouseEvent(player, "scroll", x, y, delta) } - override def copyToAnalyzer(line: Int, player: EntityPlayer): Unit = { - val stack = player.getHeldItem(EnumHand.MAIN_HAND) + override def copyToAnalyzer(line: Int, player: PlayerEntity): Unit = { + val stack = player.getItemInHand(Hand.MAIN_HAND) if (!stack.isEmpty) { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - stack.getTagCompound.removeTag(Settings.namespace + "clipboard") + stack.removeTagKey(Settings.namespace + "clipboard") if (line >= 0 && line < owner.getViewportHeight) { val text = new String(owner.data.buffer(line)).trim if (!Strings.isNullOrEmpty(text)) { - stack.getTagCompound.setString(Settings.namespace + "clipboard", text) + stack.getOrCreateTag.putString(Settings.namespace + "clipboard", text) } } - - if (stack.getTagCompound.hasNoTags) { - stack.setTagCompound(null) - } } } - private def sendMouseEvent(player: EntityPlayer, name: String, x: Double, y: Double, data: Int) = { + private def sendMouseEvent(player: PlayerEntity, name: String, x: Double, y: Double, data: Int) = { val args = mutable.ArrayBuffer.empty[AnyRef] args += player @@ -884,10 +895,10 @@ object TextBuffer { } args += Int.box(data) if (Settings.get.inputUsername) { - args += player.getName + args += player.getName.getString } - owner.node.sendToReachable("computer.checked_signal", args: _*) + owner.node.sendToReachable("computer.checked_signal", args.toSeq: _*) } private def sendToKeyboards(name: String, values: AnyRef*) { diff --git a/src/main/scala/li/cil/oc/common/component/traits/VideoRamDevice.scala b/src/main/scala/li/cil/oc/common/component/traits/VideoRamDevice.scala index 7bd2b41151..4d75c0b2bd 100644 --- a/src/main/scala/li/cil/oc/common/component/traits/VideoRamDevice.scala +++ b/src/main/scala/li/cil/oc/common/component/traits/VideoRamDevice.scala @@ -1,7 +1,7 @@ package li.cil.oc.common.component.traits import li.cil.oc.common.component -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import scala.collection.mutable trait VideoRamDevice { @@ -37,9 +37,9 @@ trait VideoRamDevice { def removeAllBuffers(): Int = removeBuffers(bufferIndexes()) - def loadBuffer(address: String, id: Int, nbt: NBTTagCompound): Unit = { + def loadBuffer(address: String, id: Int, nbt: CompoundNBT): Unit = { val src = new li.cil.oc.util.TextBuffer(width = 1, height = 1, li.cil.oc.util.PackedColor.SingleBitFormat) - src.load(nbt) + src.loadData(nbt) addBuffer(component.GpuTextBuffer.wrap(address, id, src)) } diff --git a/src/main/scala/li/cil/oc/common/component/traits/VideoRamRasterizer.scala b/src/main/scala/li/cil/oc/common/component/traits/VideoRamRasterizer.scala index 1aa3910cce..452182a6b8 100644 --- a/src/main/scala/li/cil/oc/common/component/traits/VideoRamRasterizer.scala +++ b/src/main/scala/li/cil/oc/common/component/traits/VideoRamRasterizer.scala @@ -2,8 +2,7 @@ package li.cil.oc.common.component.traits import li.cil.oc.common.component import li.cil.oc.common.component.GpuTextBuffer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.village.VillageDoorInfo +import net.minecraft.nbt.CompoundNBT import scala.collection.mutable @@ -54,7 +53,7 @@ trait VideoRamRasterizer { } } } - case _ => Unit + case _ => } count } @@ -67,9 +66,9 @@ trait VideoRamRasterizer { count } - def loadBuffer(owner: String, id: Int, nbt: NBTTagCompound): Boolean = { + def loadBuffer(owner: String, id: Int, nbt: CompoundNBT): Boolean = { val src = new li.cil.oc.util.TextBuffer(width = 1, height = 1, li.cil.oc.util.PackedColor.SingleBitFormat) - src.load(nbt) + src.loadData(nbt) addBuffer(component.GpuTextBuffer.wrap(owner, id, src)) } diff --git a/src/main/scala/li/cil/oc/common/container/Adapter.scala b/src/main/scala/li/cil/oc/common/container/Adapter.scala index c3d93ddf68..153fe27569 100644 --- a/src/main/scala/li/cil/oc/common/container/Adapter.scala +++ b/src/main/scala/li/cil/oc/common/container/Adapter.scala @@ -1,10 +1,19 @@ package li.cil.oc.common.container +import li.cil.oc.api.Driver import li.cil.oc.common.Slot +import li.cil.oc.common.Tier import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.item.ItemStack +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType + +class Adapter(selfType: ContainerType[_ <: Adapter], id: Int, playerInventory: PlayerInventory, adapter: IInventory) + extends Player(selfType, id, playerInventory, adapter) { + + override protected def getHostClass = classOf[tileentity.Adapter] -class Adapter(playerInventory: InventoryPlayer, adapter: tileentity.Adapter) extends Player(playerInventory, adapter) { addSlotToContainer(80, 35, Slot.Upgrade) addPlayerInventorySlots(8, 84) } diff --git a/src/main/scala/li/cil/oc/common/container/Assembler.scala b/src/main/scala/li/cil/oc/common/container/Assembler.scala index 8f843acb59..236cd33284 100644 --- a/src/main/scala/li/cil/oc/common/container/Assembler.scala +++ b/src/main/scala/li/cil/oc/common/container/Assembler.scala @@ -5,25 +5,39 @@ import li.cil.oc.common import li.cil.oc.common.InventorySlots.InventorySlot import li.cil.oc.common.template.AssemblerTemplates import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.item.ItemStack +import net.minecraft.inventory.container.ContainerType +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory +import net.minecraft.nbt.CompoundNBT +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +class Assembler(selfType: ContainerType[_ <: Assembler], id: Int, playerInventory: PlayerInventory, val assembler: IInventory) + extends Player(selfType, id, playerInventory, assembler) { + + override protected def getHostClass = classOf[tileentity.Assembler] -class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Assembler) extends Player(playerInventory, assembler) { // Computer case. { - val index = inventorySlots.size - addSlotToContainer(new StaticComponentSlot(this, otherInventory, index, 12, 12, "template", common.Tier.Any) { - @SideOnly(Side.CLIENT) override - def isEnabled = !isAssembling && super.isEnabled + val index = slots.size + addSlot(new StaticComponentSlot(this, otherInventory, index, 12, 12, getHostClass, "template", common.Tier.Any) { + @OnlyIn(Dist.CLIENT) override + def isActive = !isAssembling && super.isActive + override def mayPlace(stack: ItemStack): Boolean = { + if (!container.canPlaceItem(getSlotIndex, stack)) return false + if (isAssembling) return false + AssemblerTemplates.select(stack).isDefined + } + + @OnlyIn(Dist.CLIENT) override def getBackgroundLocation = if (isAssembling) Textures.Icons.get(common.Tier.None) else super.getBackgroundLocation }) } private def slotInfo(slot: DynamicComponentSlot) = { - AssemblerTemplates.select(getSlot(0).getStack) match { + AssemblerTemplates.select(getSlot(0).getItem) match { case Some(template) => val index = slot.getSlotIndex val tplSlot = @@ -36,6 +50,26 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse } } + override def addSlotToContainer(x: Int, y: Int, info: DynamicComponentSlot => InventorySlot) { + val index = slots.size + addSlot(new DynamicComponentSlot(this, otherInventory, index, x, y, getHostClass, info, () => common.Tier.One) { + override def mayPlace(stack: ItemStack): Boolean = { + if (!super.mayPlace(stack)) return false + AssemblerTemplates.select(getSlot(0).getItem) match { + case Some(template) => + val index = getSlotIndex + val tplSlot = + if ((1 until 4) contains index) template.containerSlots(index - 1) + else if ((4 until 13) contains index) template.upgradeSlots(index - 4) + else if ((13 until 21) contains index) template.componentSlots(index - 13) + else AssemblerTemplates.NoSlot + tplSlot.validate(assembler, getSlotIndex, stack) + case _ => false + } + } + }) + } + // Component containers. for (i <- 0 until 3) { addSlotToContainer(34 + i * slotSize, 70, slotInfo _) @@ -71,12 +105,17 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse def assemblyProgress = synchronizedData.getDouble("assemblyProgress") - def assemblyRemainingTime = synchronizedData.getInteger("assemblyRemainingTime") + def assemblyRemainingTime = synchronizedData.getInt("assemblyRemainingTime") - override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = { - synchronizedData.setBoolean("isAssembling", assembler.isAssembling) - synchronizedData.setDouble("assemblyProgress", assembler.progress) - synchronizedData.setInteger("assemblyRemainingTime", assembler.timeRemaining) + override protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { + assembler match { + case te: tileentity.Assembler => { + synchronizedData.putBoolean("isAssembling", te.isAssembling) + synchronizedData.putDouble("assemblyProgress", te.progress) + synchronizedData.putInt("assemblyRemainingTime", te.timeRemaining) + } + case _ => + } super.detectCustomDataChanges(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/container/Case.scala b/src/main/scala/li/cil/oc/common/container/Case.scala index 021324c215..e6b91eda97 100644 --- a/src/main/scala/li/cil/oc/common/container/Case.scala +++ b/src/main/scala/li/cil/oc/common/container/Case.scala @@ -3,48 +3,71 @@ package li.cil.oc.common.container import li.cil.oc.common.InventorySlots import li.cil.oc.common.Tier import li.cil.oc.common.tileentity -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType +import net.minecraft.util.IntReferenceHolder +import net.minecraft.util.text.ITextComponent -class Case(playerInventory: InventoryPlayer, computer: tileentity.Case) extends Player(playerInventory, computer) { - for (i <- 0 to (if (computer.tier >= Tier.Three) 2 else 1)) { - val slot = InventorySlots.computer(computer.tier)(getInventory.size) +class Case(selfType: ContainerType[_ <: Case], id: Int, playerInventory: PlayerInventory, computer: IInventory, tier: Int) + extends Player(selfType, id, playerInventory, computer) { + + override protected def getHostClass = classOf[tileentity.Case] + + for (i <- 0 to (if (tier >= Tier.Three) 2 else 1)) { + val slot = InventorySlots.computer(tier)(getItems.size) addSlotToContainer(98, 16 + i * slotSize, slot.slot, slot.tier) } - for (i <- 0 to (if (computer.tier == Tier.One) 0 else 1)) { - val slot = InventorySlots.computer(computer.tier)(getInventory.size) + for (i <- 0 to (if (tier == Tier.One) 0 else 1)) { + val slot = InventorySlots.computer(tier)(getItems.size) addSlotToContainer(120, 16 + (i + 1) * slotSize, slot.slot, slot.tier) } - for (i <- 0 to (if (computer.tier == Tier.One) 0 else 1)) { - val slot = InventorySlots.computer(computer.tier)(getInventory.size) + for (i <- 0 to (if (tier == Tier.One) 0 else 1)) { + val slot = InventorySlots.computer(tier)(getItems.size) addSlotToContainer(142, 16 + i * slotSize, slot.slot, slot.tier) } - if (computer.tier >= Tier.Three) { - val slot = InventorySlots.computer(computer.tier)(getInventory.size) + if (tier >= Tier.Three) { + val slot = InventorySlots.computer(tier)(getItems.size) addSlotToContainer(142, 16 + 2 * slotSize, slot.slot, slot.tier) } { - val slot = InventorySlots.computer(computer.tier)(getInventory.size) + val slot = InventorySlots.computer(tier)(getItems.size) addSlotToContainer(120, 16, slot.slot, slot.tier) } - if (computer.tier == Tier.One) { - val slot = InventorySlots.computer(computer.tier)(getInventory.size) + if (tier == Tier.One) { + val slot = InventorySlots.computer(tier)(getItems.size) addSlotToContainer(120, 16 + 2 * slotSize, slot.slot, slot.tier) } { - val slot = InventorySlots.computer(computer.tier)(getInventory.size) + val slot = InventorySlots.computer(tier)(getItems.size) addSlotToContainer(48, 34, slot.slot, slot.tier) } // Show the player's inventory. addPlayerInventorySlots(8, 84) - override def canInteractWith(player: EntityPlayer) = - super.canInteractWith(player) && computer.canInteract(player.getName) + private val runningData = computer match { + case te: tileentity.Case => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = if (te.isRunning) 1 else 0 + + override def set(value: Int): Unit = te.setRunning(value != 0) + }) + } + case _ => addDataSlot(IntReferenceHolder.standalone) + } + def isRunning = runningData.get != 0 + + override def stillValid(player: PlayerEntity) = + super.stillValid(player) && (computer match { + case te: tileentity.Case => te.canInteract(player.getName.getString) + case _ => true + }) } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/container/Charger.scala b/src/main/scala/li/cil/oc/common/container/Charger.scala index 0448e3ee40..f4830be052 100644 --- a/src/main/scala/li/cil/oc/common/container/Charger.scala +++ b/src/main/scala/li/cil/oc/common/container/Charger.scala @@ -1,9 +1,23 @@ package li.cil.oc.common.container +import li.cil.oc.common.Tier import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer +import li.cil.oc.integration.util.ItemCharge +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.item.ItemStack +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType -class Charger(playerInventory: InventoryPlayer, charger: tileentity.Charger) extends Player(playerInventory, charger) { - addSlotToContainer(80, 35, "tablet") +class Charger(selfType: ContainerType[_ <: Charger], id: Int, playerInventory: PlayerInventory, charger: IInventory) + extends Player(selfType, id, playerInventory, charger) { + + override protected def getHostClass = classOf[tileentity.Charger] + + addSlot(new StaticComponentSlot(this, otherInventory, slots.size, 80, 35, getHostClass, "tablet", Tier.Any) { + override def mayPlace(stack: ItemStack): Boolean = { + if (!container.canPlaceItem(getSlotIndex, stack)) return false + ItemCharge.canCharge(stack) + } + }) addPlayerInventorySlots(8, 84) } diff --git a/src/main/scala/li/cil/oc/common/container/ComponentSlot.scala b/src/main/scala/li/cil/oc/common/container/ComponentSlot.scala index 67de747f07..80350cecc2 100644 --- a/src/main/scala/li/cil/oc/common/container/ComponentSlot.scala +++ b/src/main/scala/li/cil/oc/common/container/ComponentSlot.scala @@ -1,61 +1,82 @@ package li.cil.oc.common.container +import li.cil.oc.api.Driver +import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory -import net.minecraft.inventory.Slot +import net.minecraft.inventory.container.Slot import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ -abstract class ComponentSlot(inventory: IInventory, index: Int, x: Int, y: Int) extends Slot(inventory, index, x, y) { - def container: Player +abstract class ComponentSlot(inventory: IInventory, index: Int, x: Int, y: Int, host: Class[_ <: EnvironmentHost]) extends Slot(inventory, index, x, y) { + def agentContainer: Player def slot: String def tier: Int + @OnlyIn(Dist.CLIENT) def tierIcon: ResourceLocation var changeListener: Option[Slot => Unit] = None // ----------------------------------------------------------------------- // - def hasBackground = backgroundLocation != null + @OnlyIn(Dist.CLIENT) + def hasBackground = getBackgroundLocation != null - @SideOnly(Side.CLIENT) - override def isEnabled = slot != common.Slot.None && tier != common.Tier.None && super.isEnabled + @OnlyIn(Dist.CLIENT) + def getBackgroundLocation: ResourceLocation = null - override def isItemValid(stack: ItemStack) = inventory.isItemValidForSlot(getSlotIndex, stack) + @OnlyIn(Dist.CLIENT) + override def isActive = slot != common.Slot.None && tier != common.Tier.None && super.isActive - override def onTake(player: EntityPlayer, stack: ItemStack) = { - for (slot <- container.inventorySlots) slot match { + override def mayPlace(stack: ItemStack): Boolean = { + if (!inventory.canPlaceItem(getSlotIndex, stack)) return false + if (slot == common.Slot.None || tier == common.Tier.None) return false + if (slot == common.Slot.Any && tier == common.Tier.Any) return true + // Special case: tool slots fit everything. + if (slot == common.Slot.Tool) return true + Option(Driver.driverFor(stack, host)) match { + case Some(driver) => { + val slotOk = (slot == common.Slot.Any || driver.slot(stack) == slot) + val tierOk = (tier == common.Tier.Any || driver.tier(stack) <= tier) + slotOk && tierOk + } + case _ => false + } + } + + override def onTake(player: PlayerEntity, stack: ItemStack) = { + for (slot <- agentContainer.slots) slot match { case dynamic: ComponentSlot => dynamic.clearIfInvalid(player) case _ => } super.onTake(player, stack) } - override def putStack(stack: ItemStack): Unit = { - super.putStack(stack) + override def set(stack: ItemStack): Unit = { + super.set(stack) inventory match { case playerAware: common.tileentity.traits.PlayerInputAware => - playerAware.onSetInventorySlotContents(container.playerInventory.player, getSlotIndex, stack) + playerAware.onSetInventorySlotContents(agentContainer.playerInventory.player, getSlotIndex, stack) case _ => } } - override def onSlotChanged() { - super.onSlotChanged() - for (slot <- container.inventorySlots) slot match { - case dynamic: ComponentSlot => dynamic.clearIfInvalid(container.playerInventory.player) + override def setChanged() { + super.setChanged() + for (slot <- agentContainer.slots) slot match { + case dynamic: ComponentSlot => dynamic.clearIfInvalid(agentContainer.playerInventory.player) case _ => } changeListener.foreach(_(this)) } - protected def clearIfInvalid(player: EntityPlayer) {} + protected def clearIfInvalid(player: PlayerEntity) {} } diff --git a/src/main/scala/li/cil/oc/common/container/ContainerTypes.java b/src/main/scala/li/cil/oc/common/container/ContainerTypes.java new file mode 100644 index 0000000000..c6af141266 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/container/ContainerTypes.java @@ -0,0 +1,179 @@ +package li.cil.oc.common.container; + +import li.cil.oc.OpenComputers; +import net.minecraft.item.ItemStack; +import net.minecraft.inventory.Inventory; +import net.minecraft.inventory.container.ContainerType; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.extensions.IForgeContainerType; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.network.IContainerFactory; +import net.minecraftforge.fml.network.NetworkHooks; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.ObjectHolder; + +@ObjectHolder("opencomputers") +public final class ContainerTypes { + public static final ContainerType ADAPTER = null; + public static final ContainerType ASSEMBLER = null; + public static final ContainerType CASE = null; + public static final ContainerType CHARGER = null; + public static final ContainerType DATABASE = null; + public static final ContainerType DISASSEMBLER = null; + public static final ContainerType DISK_DRIVE = null; + public static final ContainerType DRONE = null; + public static final ContainerType PRINTER = null; + public static final ContainerType RACK = null; + public static final ContainerType RAID = null; + public static final ContainerType RELAY = null; + public static final ContainerType ROBOT = null; + public static final ContainerType SERVER = null; + public static final ContainerType TABLET = null; + + @SubscribeEvent + public static void registerContainers(RegistryEvent.Register> e) { + register(e.getRegistry(), "adapter", (id, plr, buff) -> new Adapter(ADAPTER, id, plr, new Inventory(1))); + register(e.getRegistry(), "assembler", (id, plr, buff) -> new Assembler(ASSEMBLER, id, plr, new Inventory(22))); + register(e.getRegistry(), "case", (id, plr, buff) -> { + int invSize = buff.readVarInt(); + int tier = buff.readVarInt(); + return new Case(CASE, id, plr, new Inventory(invSize), tier); + }); + register(e.getRegistry(), "charger", (id, plr, buff) -> new Charger(CHARGER, id, plr, new Inventory(1))); + register(e.getRegistry(), "database", (id, plr, buff) -> { + ItemStack containerStack = buff.readItem(); + int invSize = buff.readVarInt(); + int tier = buff.readVarInt(); + return new Database(DATABASE, id, plr, containerStack, new Inventory(invSize), tier); + }); + register(e.getRegistry(), "disassembler", (id, plr, buff) -> new Disassembler(DISASSEMBLER, id, plr, new Inventory(1))); + register(e.getRegistry(), "disk_drive", (id, plr, buff) -> new DiskDrive(DISK_DRIVE, id, plr, new Inventory(1))); + register(e.getRegistry(), "drone", (id, plr, buff) -> { + int invSize = buff.readVarInt(); + return new Drone(DRONE, id, plr, new Inventory(8), invSize); + }); + register(e.getRegistry(), "printer", (id, plr, buff) -> new Printer(PRINTER, id, plr, new Inventory(3))); + register(e.getRegistry(), "rack", (id, plr, buff) -> new Rack(RACK, id, plr, new Inventory(4))); + register(e.getRegistry(), "raid", (id, plr, buff) -> new Raid(RAID, id, plr, new Inventory(3))); + register(e.getRegistry(), "relay", (id, plr, buff) -> new Relay(RELAY, id, plr, new Inventory(4))); + register(e.getRegistry(), "robot", (id, plr, buff) -> { + RobotInfo info = RobotInfo$.MODULE$.readRobotInfo(buff); + return new Robot(ROBOT, id, plr, new Inventory(100), info); + }); + register(e.getRegistry(), "server", (id, plr, buff) -> { + ItemStack containerStack = buff.readItem(); + int invSize = buff.readVarInt(); + int tier = buff.readVarInt(); + int rackSlot = buff.readVarInt() - 1; + return new Server(SERVER, id, plr, containerStack, new Inventory(invSize), tier, rackSlot); + }); + register(e.getRegistry(), "tablet", (id, plr, buff) -> { + ItemStack containerStack = buff.readItem(); + int invSize = buff.readVarInt(); + String slot1 = buff.readUtf(32); + int tier1 = buff.readVarInt(); + return new Tablet(TABLET, id, plr, containerStack, new Inventory(invSize), slot1, tier1); + }); + } + + private static void register(IForgeRegistry> registry, String name, IContainerFactory factory) { + ContainerType type = IForgeContainerType.create(factory); + type.setRegistryName(new ResourceLocation(OpenComputers.ID(), name)); + registry.register(type); + } + + public static void openAdapterGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Adapter adapter) { + NetworkHooks.openGui(player, adapter); + } + + public static void openAssemblerGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Assembler assembler) { + NetworkHooks.openGui(player, assembler); + } + + public static void openCaseGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Case computer) { + NetworkHooks.openGui(player, computer, buff -> { + buff.writeVarInt(computer.getContainerSize()); + buff.writeVarInt(computer.tier()); + }); + } + + public static void openChargerGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Charger charger) { + NetworkHooks.openGui(player, charger); + } + + public static void openDatabaseGui(ServerPlayerEntity player, li.cil.oc.common.inventory.DatabaseInventory database) { + NetworkHooks.openGui(player, database, buff -> { + buff.writeItem(database.container()); + buff.writeVarInt(database.getContainerSize()); + buff.writeVarInt(database.tier()); + }); + } + + public static void openDisassemblerGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Disassembler disassembler) { + NetworkHooks.openGui(player, disassembler); + } + + public static void openDiskDriveGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.DiskDrive diskDrive) { + NetworkHooks.openGui(player, diskDrive); + } + + public static void openDiskDriveGui(ServerPlayerEntity player, li.cil.oc.server.component.DiskDriveMountable diskDrive) { + NetworkHooks.openGui(player, diskDrive); + } + + public static void openDiskDriveGui(ServerPlayerEntity player, li.cil.oc.common.inventory.DiskDriveMountableInventory diskDrive) { + NetworkHooks.openGui(player, diskDrive); + } + + public static void openDroneGui(ServerPlayerEntity player, li.cil.oc.common.entity.Drone drone) { + NetworkHooks.openGui(player, drone.containerProvider(), buff -> { + buff.writeVarInt(drone.mainInventory().getContainerSize()); + }); + } + + public static void openPrinterGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Printer printer) { + NetworkHooks.openGui(player, printer); + } + + public static void openRackGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Rack rack) { + NetworkHooks.openGui(player, rack); + } + + public static void openRaidGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Raid raid) { + NetworkHooks.openGui(player, raid); + } + + public static void openRelayGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Relay relay) { + NetworkHooks.openGui(player, relay); + } + + public static void openRobotGui(ServerPlayerEntity player, li.cil.oc.common.tileentity.Robot robot) { + NetworkHooks.openGui(player, robot, buff -> { + RobotInfo$.MODULE$.writeRobotInfo(buff, new RobotInfo(robot)); + }); + } + + public static void openServerGui(ServerPlayerEntity player, li.cil.oc.common.inventory.ServerInventory server, int rackSlot) { + NetworkHooks.openGui(player, server, buff -> { + buff.writeItem(server.container()); + buff.writeVarInt(server.getContainerSize()); + buff.writeVarInt(server.tier()); + buff.writeVarInt(rackSlot + 1); + }); + } + + public static void openTabletGui(ServerPlayerEntity player, li.cil.oc.common.item.TabletWrapper tablet) { + NetworkHooks.openGui(player, tablet, buff -> { + buff.writeItem(tablet.stack()); + buff.writeVarInt(tablet.getContainerSize()); + buff.writeUtf(tablet.containerSlotType(), 32); + buff.writeVarInt(tablet.containerSlotTier()); + }); + } + + private ContainerTypes() { + throw new Error(); + } +} diff --git a/src/main/scala/li/cil/oc/common/container/Database.scala b/src/main/scala/li/cil/oc/common/container/Database.scala index b3201ec444..1c115fc0cc 100644 --- a/src/main/scala/li/cil/oc/common/container/Database.scala +++ b/src/main/scala/li/cil/oc/common/container/Database.scala @@ -1,14 +1,21 @@ package li.cil.oc.common.container import li.cil.oc.common.inventory.DatabaseInventory -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.inventory._ +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ClickType +import net.minecraft.inventory.container.ContainerType +import net.minecraft.inventory.container.Slot import net.minecraft.item.ItemStack -class Database(playerInventory: InventoryPlayer, databaseInventory: DatabaseInventory) extends Player(playerInventory, databaseInventory) { - val rows = math.sqrt(databaseInventory.getSizeInventory).ceil.toInt - val offset = 8 + Array(3, 2, 0)(databaseInventory.tier) * slotSize +class Database(selfType: ContainerType[_ <: Database], id: Int, playerInventory: PlayerInventory, val container: ItemStack, databaseInventory: IInventory, val tier: Int) + extends Player(selfType, id, playerInventory, databaseInventory) { + + override protected def getHostClass = null + + val rows = math.sqrt(databaseInventory.getContainerSize).ceil.toInt + val offset = 8 + Array(3, 2, 0)(tier) * slotSize for (row <- 0 until rows; col <- 0 until rows) { addSlotToContainer(offset + col * slotSize, offset + row * slotSize) @@ -17,49 +24,49 @@ class Database(playerInventory: InventoryPlayer, databaseInventory: DatabaseInve // Show the player's inventory. addPlayerInventorySlots(8, 174) - override def canInteractWith(player: EntityPlayer) = player == playerInventory.player + override def stillValid(player: PlayerEntity) = player == playerInventory.player - override def slotClick(slot: Int, dragType: Int, clickType: ClickType, player: EntityPlayer): ItemStack = { - if (slot >= databaseInventory.getSizeInventory() || slot < 0) { + override def clicked(slot: Int, dragType: Int, clickType: ClickType, player: PlayerEntity): ItemStack = { + if (slot >= databaseInventory.getContainerSize() || slot < 0) { // if the slot interaction is with the user inventory use // default behavior - return super.slotClick(slot, dragType, clickType, player) + return super.clicked(slot, dragType, clickType, player) } // remove the ghost item - val ghostSlot = this.inventorySlots.get(slot); + val ghostSlot = this.slots.get(slot); if (ghostSlot != null) { val inventoryPlayer = player.inventory - val hand = inventoryPlayer.getItemStack() + val hand = inventoryPlayer.getCarried() var itemToAdd = ItemStack.EMPTY // if the player is holding an item, place a copy if (!hand.isEmpty()) { itemToAdd = hand.copy() } - ghostSlot.putStack(itemToAdd) + ghostSlot.set(itemToAdd) } ItemStack.EMPTY } override protected def tryTransferStackInSlot(from: Slot, intoPlayerInventory: Boolean) { if (intoPlayerInventory) { - from.onSlotChanged() + from.setChanged() return } - val fromStack = from.getStack().copy() + val fromStack = from.getItem().copy() if (fromStack.isEmpty) { return } fromStack.setCount(1) - val (begin, end) = (0, inventorySlots.size - 1) + val (begin, end) = (0, slots.size - 1) for (i <- begin to end) { - val intoSlot = inventorySlots.get(i) - if (intoSlot.inventory != from.inventory) { - if (!intoSlot.getHasStack && intoSlot.isItemValid(fromStack)) { - if (intoSlot.getSlotStackLimit > 0) { - intoSlot.putStack(fromStack) + val intoSlot = slots.get(i) + if (intoSlot.container != from.container) { + if (!intoSlot.hasItem && intoSlot.mayPlace(fromStack)) { + if (intoSlot.getMaxStackSize > 0) { + intoSlot.set(fromStack) return } } diff --git a/src/main/scala/li/cil/oc/common/container/Disassembler.scala b/src/main/scala/li/cil/oc/common/container/Disassembler.scala index 248e137b8d..3aa743908a 100644 --- a/src/main/scala/li/cil/oc/common/container/Disassembler.scala +++ b/src/main/scala/li/cil/oc/common/container/Disassembler.scala @@ -1,17 +1,43 @@ package li.cil.oc.common.container +import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.common.Slot +import li.cil.oc.common.Tier +import li.cil.oc.common.template.DisassemblerTemplates import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.nbt.NBTTagCompound +import li.cil.oc.util.ItemUtils +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.item.ItemStack +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType +import net.minecraft.nbt.CompoundNBT -class Disassembler(playerInventory: InventoryPlayer, val disassembler: tileentity.Disassembler) extends Player(playerInventory, disassembler) { - addSlotToContainer(80, 35, "ocitem") +class Disassembler(selfType: ContainerType[_ <: Disassembler], id: Int, playerInventory: PlayerInventory, val disassembler: IInventory) + extends Player(selfType, id, playerInventory, disassembler) { + + private def allowDisassembling(stack: ItemStack) = !stack.isEmpty && (!stack.hasTag || !stack.getTag.getBoolean(Settings.namespace + "undisassemblable")) + + override protected def getHostClass = classOf[tileentity.Disassembler] + + addSlot(new StaticComponentSlot(this, otherInventory, slots.size, 80, 35, getHostClass, "ocitem", Tier.Any) { + override def mayPlace(stack: ItemStack): Boolean = { + if (!container.canPlaceItem(getSlotIndex, stack)) return false + allowDisassembling(stack) && + (((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && + ItemUtils.getIngredients(playerInventory.player.level.getRecipeManager, stack).nonEmpty) || + DisassemblerTemplates.select(stack).isDefined) + } + }) addPlayerInventorySlots(8, 84) def disassemblyProgress = synchronizedData.getDouble("disassemblyProgress") - override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = { - synchronizedData.setDouble("disassemblyProgress", disassembler.progress) + override protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { + disassembler match { + case te: tileentity.Disassembler => synchronizedData.putDouble("disassemblyProgress", te.progress) + case _ => + } super.detectCustomDataChanges(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/container/DiskDrive.scala b/src/main/scala/li/cil/oc/common/container/DiskDrive.scala index 8a2c4b3fbf..9dedf16e12 100644 --- a/src/main/scala/li/cil/oc/common/container/DiskDrive.scala +++ b/src/main/scala/li/cil/oc/common/container/DiskDrive.scala @@ -1,10 +1,16 @@ package li.cil.oc.common.container import li.cil.oc.common.Slot -import net.minecraft.entity.player.InventoryPlayer +import li.cil.oc.common.tileentity +import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType + +class DiskDrive(selfType: ContainerType[_ <: DiskDrive], id: Int, playerInventory: PlayerInventory, drive: IInventory) + extends Player(selfType, id, playerInventory, drive) { + + override protected def getHostClass = classOf[tileentity.DiskDrive] -class DiskDrive(playerInventory: InventoryPlayer, drive: IInventory) extends Player(playerInventory, drive) { addSlotToContainer(80, 35, Slot.Floppy) addPlayerInventorySlots(8, 84) } diff --git a/src/main/scala/li/cil/oc/common/container/Drone.scala b/src/main/scala/li/cil/oc/common/container/Drone.scala index fb978f074c..34326a219d 100644 --- a/src/main/scala/li/cil/oc/common/container/Drone.scala +++ b/src/main/scala/li/cil/oc/common/container/Drone.scala @@ -3,37 +3,110 @@ package li.cil.oc.common.container import li.cil.oc.client.Textures import li.cil.oc.common import li.cil.oc.common.entity -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType import net.minecraft.item.ItemStack -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.IntReferenceHolder +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +class Drone(selfType: ContainerType[_ <: Drone], id: Int, playerInventory: PlayerInventory, droneInv: IInventory, val mainInvSize: Int) + extends Player(selfType, id, playerInventory, droneInv) { -class Drone(playerInventory: InventoryPlayer, drone: entity.Drone) extends Player(playerInventory, drone.mainInventory) { val deltaY = 0 + override protected def getHostClass = classOf[entity.Drone] + for (i <- 0 to 1) { val y = 8 + i * slotSize - deltaY for (j <- 0 to 3) { val x = 98 + j * slotSize - addSlotToContainer(new InventorySlot(this, otherInventory, inventorySlots.size, x, y)) + addSlot(new InventorySlot(this, otherInventory, slots.size, x, y)) } } addPlayerInventorySlots(8, 66) - class InventorySlot(container: Player, inventory: IInventory, index: Int, x: Int, y: Int) extends StaticComponentSlot(container, inventory, index, x, y, common.Slot.Any, common.Tier.Any) { - def isValid = (0 until drone.mainInventory.getSizeInventory).contains(getSlotIndex) + // This factor is used to make the energy values transferable using + // MCs 'progress bar' stuff, even though those internally send the + // values as shorts over the net (for whatever reason). + private val factor = 100 + + private val globalBufferData = droneInv match { + case droneInv: entity.DroneInventory => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = droneInv.drone.globalBuffer / factor + + override def set(value: Int): Unit = droneInv.drone.globalBuffer = value * factor + }) + } + case _ => addDataSlot(IntReferenceHolder.standalone) + } + def globalBuffer = globalBufferData.get * factor + + private val globalBufferSizeData = droneInv match { + case droneInv: entity.DroneInventory => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = droneInv.drone.globalBufferSize / factor + + override def set(value: Int): Unit = droneInv.drone.globalBufferSize = value * factor + }) + } + case _ => addDataSlot(IntReferenceHolder.standalone) + } + def globalBufferSize = globalBufferSizeData.get * factor + + private val runningData = droneInv match { + case droneInv: entity.DroneInventory => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = if (droneInv.drone.isRunning) 1 else 0 + + override def set(value: Int): Unit = droneInv.drone.setRunning(value != 0) + }) + } + case _ => addDataSlot(IntReferenceHolder.standalone) + } + def isRunning = runningData.get != 0 + + private val selectedSlotData = droneInv match { + case droneInv: entity.DroneInventory => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = droneInv.drone.selectedSlot + + override def set(value: Int): Unit = droneInv.drone.setSelectedSlot(value) + }) + } + case _ => addDataSlot(IntReferenceHolder.standalone) + } + def selectedSlot = selectedSlotData.get + + def statusText = synchronizedData.getString("statusText") + + override protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { + droneInv match { + case droneInv: entity.DroneInventory => synchronizedData.putString("statusText", droneInv.drone.statusText) + case _ => + } + super.detectCustomDataChanges(nbt) + } + + class InventorySlot(container: Player, inventory: IInventory, index: Int, x: Int, y: Int) + extends StaticComponentSlot(container, inventory, index, x, y, getHostClass, common.Slot.Any, common.Tier.Any) { + + def isValid = (0 until mainInvSize).contains(getSlotIndex) - @SideOnly(Side.CLIENT) override - def isEnabled = isValid && super.isEnabled + @OnlyIn(Dist.CLIENT) override + def isActive = isValid && super.isActive + @OnlyIn(Dist.CLIENT) override def getBackgroundLocation = if (isValid) super.getBackgroundLocation else Textures.Icons.get(common.Tier.None) - override def getStack = { - if (isValid) super.getStack + override def getItem = { + if (isValid) super.getItem else ItemStack.EMPTY } } diff --git a/src/main/scala/li/cil/oc/common/container/DynamicComponentSlot.scala b/src/main/scala/li/cil/oc/common/container/DynamicComponentSlot.scala index 612a0e5a7f..9738fda3ad 100644 --- a/src/main/scala/li/cil/oc/common/container/DynamicComponentSlot.scala +++ b/src/main/scala/li/cil/oc/common/container/DynamicComponentSlot.scala @@ -1,22 +1,29 @@ package li.cil.oc.common.container +import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.client.Textures import li.cil.oc.common import li.cil.oc.common.InventorySlots.InventorySlot import li.cil.oc.util.InventoryUtils import li.cil.oc.util.SideTracker -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +class DynamicComponentSlot(val agentContainer: Player, inventory: IInventory, index: Int, x: Int, y: Int, host: Class[_ <: EnvironmentHost], + val info: DynamicComponentSlot => InventorySlot, val containerTierGetter: () => Int) + extends ComponentSlot(inventory, index, x, y, host) { -class DynamicComponentSlot(val container: Player, inventory: IInventory, index: Int, x: Int, y: Int, val info: DynamicComponentSlot => InventorySlot, val containerTierGetter: () => Int) extends ComponentSlot(inventory, index, x, y) { override def tier: Int = { val mainTier = containerTierGetter() if (mainTier >= 0) info(this).tier else mainTier } + @OnlyIn(Dist.CLIENT) def tierIcon: ResourceLocation = Textures.Icons.get(tier) def slot: String = { @@ -25,21 +32,23 @@ class DynamicComponentSlot(val container: Player, inventory: IInventory, index: else common.Slot.None } + @OnlyIn(Dist.CLIENT) override def hasBackground: Boolean = Textures.Icons.get(slot) != null + @OnlyIn(Dist.CLIENT) override def getBackgroundLocation: ResourceLocation = Option(Textures.Icons.get(slot)).getOrElse(super.getBackgroundLocation) - override def getSlotStackLimit: Int = + override def getMaxStackSize: Int = slot match { - case common.Slot.Tool | common.Slot.Any | common.Slot.Filtered => super.getSlotStackLimit + case common.Slot.Tool | common.Slot.Any | common.Slot.Filtered => super.getMaxStackSize case common.Slot.None => 0 case _ => 1 } - override protected def clearIfInvalid(player: EntityPlayer) { - if (SideTracker.isServer && getHasStack && !isItemValid(getStack)) { - val stack = getStack - putStack(ItemStack.EMPTY) + override protected def clearIfInvalid(player: PlayerEntity) { + if (SideTracker.isServer && hasItem && !mayPlace(getItem)) { + val stack = getItem + set(ItemStack.EMPTY) InventoryUtils.addToPlayerInventory(stack, player) } } diff --git a/src/main/scala/li/cil/oc/common/container/InternalSlot.scala b/src/main/scala/li/cil/oc/common/container/InternalSlot.scala deleted file mode 100644 index 43156ecdcf..0000000000 --- a/src/main/scala/li/cil/oc/common/container/InternalSlot.scala +++ /dev/null @@ -1,5 +0,0 @@ -package li.cil.oc.common.container - -object InternalSlot extends Enumeration { - val Server = Value -} diff --git a/src/main/scala/li/cil/oc/common/container/Player.scala b/src/main/scala/li/cil/oc/common/container/Player.scala index 64f20eae05..1aeeebc872 100644 --- a/src/main/scala/li/cil/oc/common/container/Player.scala +++ b/src/main/scala/li/cil/oc/common/container/Player.scala @@ -1,51 +1,65 @@ package li.cil.oc.common.container +import java.util.Arrays + +import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common import li.cil.oc.common.InventorySlots.InventorySlot import li.cil.oc.common.Tier import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.SideTracker -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory._ +import net.minecraft.inventory.container.ClickType +import net.minecraft.inventory.container.Container +import net.minecraft.inventory.container.ContainerType +import net.minecraft.inventory.container.IContainerListener +import net.minecraft.inventory.container.Slot import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTBase -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.ByteArrayNBT +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.INBT +import net.minecraft.nbt.IntArrayNBT +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import net.minecraftforge.common.util.FakePlayer -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ +import scala.collection.mutable -abstract class Player(val playerInventory: InventoryPlayer, val otherInventory: IInventory) extends Container { +abstract class Player(selfType: ContainerType[_ <: Player], id: Int, val playerInventory: PlayerInventory, val otherInventory: IInventory) extends Container(selfType, id) { /** Number of player inventory slots to display horizontally. */ - protected val playerInventorySizeX = math.min(9, InventoryPlayer.getHotbarSize) + protected val playerInventorySizeX = math.min(9, PlayerInventory.getSelectionSize) - /** Subtract four for armor slots. */ - protected val playerInventorySizeY = math.min(4, (playerInventory.getSizeInventory - 4) / playerInventorySizeX) + protected val playerInventorySizeY = math.min(4, playerInventory.items.size / playerInventorySizeX) /** Render size of slots (width and height). */ protected val slotSize = 18 private var lastSync = System.currentTimeMillis() - override def canInteractWith(player: EntityPlayer) = otherInventory.isUsableByPlayer(player) + protected val playerListeners = mutable.ArrayBuffer.empty[ServerPlayerEntity] + + override def stillValid(player: PlayerEntity) = otherInventory.stillValid(player) - override def slotClick(slot: Int, dragType: Int, clickType: ClickType, player: EntityPlayer): ItemStack = { - val result = super.slotClick(slot, dragType, clickType, player) + override def clicked(slot: Int, dragType: Int, clickType: ClickType, player: PlayerEntity): ItemStack = { + val result = super.clicked(slot, dragType, clickType, player) if (SideTracker.isServer) { - detectAndSendChanges() // We have to enforce this more than MC does itself + broadcastChanges() // We have to enforce this more than MC does itself // because stacks can change their... "character" just by being inserted in // certain containers - by being assigned an address. } result } - override def transferStackInSlot(player: EntityPlayer, index: Int): ItemStack = { - val slot = Option(inventorySlots.get(index)).orNull - if (slot != null && slot.getHasStack) { - tryTransferStackInSlot(slot, slot.inventory == otherInventory) + override def quickMoveStack(player: PlayerEntity, index: Int): ItemStack = { + val slot = Option(slots.get(index)).orNull + if (slot != null && slot.hasItem) { + tryTransferStackInSlot(slot, slot.container == otherInventory) if (SideTracker.isServer) { - detectAndSendChanges() + broadcastChanges() } } ItemStack.EMPTY @@ -57,30 +71,30 @@ abstract class Player(val playerInventory: InventoryPlayer, val otherInventory: return false // nowhere to move it if (from == null || - !from.getHasStack || - from.getStack.isEmpty) + !from.hasItem || + from.getItem.isEmpty) return true // all moved because nothing to move - if (to.inventory == from.inventory) + if (to.container == from.container) return false // not intended for moving in the same inventory // for ghost slots we don't care about stack size - val fromStack = from.getStack - val toStack = if (to.getHasStack) to.getStack else ItemStack.EMPTY + val fromStack = from.getItem + val toStack = if (to.hasItem) to.getItem else ItemStack.EMPTY val toStackSize = if (!toStack.isEmpty) toStack.getCount else 0 - val maxStackSize = math.min(fromStack.getMaxStackSize, to.getSlotStackLimit) + val maxStackSize = math.min(fromStack.getMaxStackSize, to.getMaxStackSize) val itemsMoved = math.min(maxStackSize - toStackSize, fromStack.getCount) if (!toStack.isEmpty) { if (toStackSize < maxStackSize && - fromStack.isItemEqual(toStack) && - ItemStack.areItemStackTagsEqual(fromStack, toStack) && + fromStack.sameItem(toStack) && + ItemStack.tagMatches(fromStack, toStack) && itemsMoved > 0) { - toStack.grow(from.decrStackSize(itemsMoved).getCount) + toStack.grow(from.remove(itemsMoved).getCount) } else return false - } else if (to.isItemValid(fromStack)) { - to.putStack(from.decrStackSize(itemsMoved)) + } else if (to.mayPlace(fromStack)) { + to.set(from.remove(itemsMoved)) if (maxStackSize == 0) { // Special case: we have an inventory with "phantom/ghost stacks", i.e. // zero size stacks, usually used for configuring machinery. In that @@ -92,14 +106,14 @@ abstract class Player(val playerInventory: InventoryPlayer, val otherInventory: } } else return false - to.onSlotChanged() - from.onSlotChanged() + to.setChanged() + from.setChanged() false } protected def fillOrder(backFill: Boolean): Seq[Int] = { - (if (backFill) inventorySlots.indices.reverse else inventorySlots.indices).sortBy(i => inventorySlots(i) match { - case s: Slot if s.getHasStack => -1 + (if (backFill) slots.indices.reverse else slots.indices).sortBy(i => slots(i) match { + case s: Slot if s.hasItem => -1 case s: ComponentSlot => s.tier case _ => 99 }) @@ -107,24 +121,27 @@ abstract class Player(val playerInventory: InventoryPlayer, val otherInventory: protected def tryTransferStackInSlot(from: Slot, intoPlayerInventory: Boolean) { for (i <- fillOrder(intoPlayerInventory)) { - if (inventorySlots.get(i) match { case slot: Slot => tryMoveAllSlotToSlot(from, slot) case _ => false }) + if (slots.get(i) match { case slot: Slot => tryMoveAllSlotToSlot(from, slot) case _ => false }) return } } + // Used by the ComponentSlots to make host-aware item placement decisions. + protected def getHostClass: Class[_ <: EnvironmentHost] + def addSlotToContainer(x: Int, y: Int, slot: String = common.Slot.Any, tier: Int = common.Tier.Any) { - val index = inventorySlots.size - addSlotToContainer(new StaticComponentSlot(this, otherInventory, index, x, y, slot, tier)) + val index = slots.size + addSlot(new StaticComponentSlot(this, otherInventory, index, x, y, getHostClass, slot, tier)) } def addSlotToContainer(x: Int, y: Int, info: Array[Array[InventorySlot]], containerTierGetter: () => Int) { - val index = inventorySlots.size - addSlotToContainer(new DynamicComponentSlot(this, otherInventory, index, x, y, slot => info(slot.containerTierGetter())(slot.getSlotIndex), containerTierGetter)) + val index = slots.size + addSlot(new DynamicComponentSlot(this, otherInventory, index, x, y, getHostClass, slot => info(slot.containerTierGetter())(slot.getSlotIndex), containerTierGetter)) } def addSlotToContainer(x: Int, y: Int, info: DynamicComponentSlot => InventorySlot) { - val index = inventorySlots.size - addSlotToContainer(new DynamicComponentSlot(this, otherInventory, index, x, y, info, () => Tier.One)) + val index = slots.size + addSlot(new DynamicComponentSlot(this, otherInventory, index, x, y, getHostClass, info, () => Tier.One)) } /** Render player inventory at the specified coordinates. */ @@ -136,7 +153,7 @@ abstract class Player(val playerInventory: InventoryPlayer, val otherInventory: val x = left + slotX * slotSize // Compensate for hot bar offset. val y = top + (slotY - 1) * slotSize - addSlotToContainer(new Slot(playerInventory, index, x, y)) + addSlot(new Slot(playerInventory, index, x, y)) } } @@ -145,113 +162,126 @@ abstract class Player(val playerInventory: InventoryPlayer, val otherInventory: for (index <- 0 until playerInventorySizeX) { val x = left + index * slotSize val y = top + slotSize * (playerInventorySizeY - 1) + quickBarSpacing - addSlotToContainer(new Slot(playerInventory, index, x, y)) + addSlot(new Slot(playerInventory, index, x, y)) + } + } + + override def addSlotListener(listener: IContainerListener): Unit = { + listener match { + case _: FakePlayer => // Nope + case player: ServerPlayerEntity => playerListeners += player + case _ => } + super.addSlotListener(listener) } - protected def sendWindowProperty(id: Int, value: Int) { - listeners.foreach(_.sendWindowProperty(this, id, value)) + @OnlyIn(Dist.CLIENT) + override def removeSlotListener(listener: IContainerListener): Unit = { + if (listener.isInstanceOf[ServerPlayerEntity]) playerListeners -= listener.asInstanceOf[ServerPlayerEntity] + super.removeSlotListener(listener) } - override def detectAndSendChanges(): Unit = { - super.detectAndSendChanges() + override def broadcastChanges(): Unit = { + super.broadcastChanges() if (SideTracker.isServer) { - val nbt = new NBTTagCompound() + val nbt = new CompoundNBT() detectCustomDataChanges(nbt) - for (entry <- listeners) entry match { - case _: FakePlayer => // Nope - case player: EntityPlayerMP => ServerPacketSender.sendContainerUpdate(this, nbt, player) - case _ => - } + for (player <- playerListeners) ServerPacketSender.sendContainerUpdate(this, nbt, player) } } // Used for custom value synchronization, because shorts simply don't cut it most of the time. - protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = { + protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { val delta = synchronizedData.getDelta - if (delta != null && !delta.hasNoTags) { - nbt.setTag("delta", delta) + if (delta != null && !delta.isEmpty) { + nbt.put("delta", delta) } else if (System.currentTimeMillis() - lastSync > 250) { - nbt.setTag("delta", synchronizedData) + nbt.put("delta", synchronizedData) lastSync = Long.MaxValue } } - def updateCustomData(nbt: NBTTagCompound): Unit = { - if (nbt.hasKey("delta")) { - val delta = nbt.getCompoundTag("delta") - delta.getKeySet.foreach { - case key: String => synchronizedData.setTag(key, delta.getTag(key)) + def updateCustomData(nbt: CompoundNBT): Unit = { + if (nbt.contains("delta")) { + val delta = nbt.getCompound("delta") + delta.getAllKeys.foreach { + case key: String => synchronizedData.put(key, delta.get(key)) } } } - protected class SynchronizedData extends NBTTagCompound { - private var delta = new NBTTagCompound() + protected class SynchronizedData extends CompoundNBT { + private var delta = new CompoundNBT() - def getDelta: NBTTagCompound = this.synchronized { - if (delta.hasNoTags) null + def getDelta: CompoundNBT = this.synchronized { + if (delta.isEmpty) null else { val result = delta - delta = new NBTTagCompound() + delta = new CompoundNBT() result } } - override def setTag(key: String, value: NBTBase): Unit = this.synchronized { - if (!value.equals(getTag(key))) delta.setTag(key, value) - super.setTag(key, value) + override def put(key: String, value: INBT): INBT = this.synchronized { + if (!value.equals(get(key))) delta.put(key, value) + super.put(key, value) } - override def setByte(key: String, value: Byte): Unit = this.synchronized { - if (value != getByte(key)) delta.setByte(key, value) - super.setByte(key, value) + override def putByte(key: String, value: Byte): Unit = this.synchronized { + if (value != getByte(key)) delta.putByte(key, value) + super.putByte(key, value) } - override def setShort(key: String, value: Short): Unit = this.synchronized { - if (value != getShort(key)) delta.setShort(key, value) - super.setShort(key, value) + override def putShort(key: String, value: Short): Unit = this.synchronized { + if (value != getShort(key)) delta.putShort(key, value) + super.putShort(key, value) } - override def setInteger(key: String, value: Int): Unit = this.synchronized { - if (value != getInteger(key)) delta.setInteger(key, value) - super.setInteger(key, value) + override def putInt(key: String, value: Int): Unit = this.synchronized { + if (value != getInt(key)) delta.putInt(key, value) + super.putInt(key, value) } - override def setLong(key: String, value: Long): Unit = this.synchronized { - if (value != getLong(key)) delta.setLong(key, value) - super.setLong(key, value) + override def putLong(key: String, value: Long): Unit = this.synchronized { + if (value != getLong(key)) delta.putLong(key, value) + super.putLong(key, value) } - override def setFloat(key: String, value: Float): Unit = this.synchronized { - if (value != getFloat(key)) delta.setFloat(key, value) - super.setFloat(key, value) + override def putFloat(key: String, value: Float): Unit = this.synchronized { + if (value != getFloat(key)) delta.putFloat(key, value) + super.putFloat(key, value) } - override def setDouble(key: String, value: Double): Unit = this.synchronized { - if (value != getDouble(key)) delta.setDouble(key, value) - super.setDouble(key, value) + override def putDouble(key: String, value: Double): Unit = this.synchronized { + if (value != getDouble(key)) delta.putDouble(key, value) + super.putDouble(key, value) } - override def setString(key: String, value: String): Unit = this.synchronized { - if (value != getString(key)) delta.setString(key, value) - super.setString(key, value) + override def putString(key: String, value: String): Unit = this.synchronized { + if (value != getString(key)) delta.putString(key, value) + super.putString(key, value) } - override def setByteArray(key: String, value: Array[Byte]): Unit = this.synchronized { - if (value.deep != getByteArray(key).deep) delta.setByteArray(key, value) - super.setByteArray(key, value) + override def putByteArray(key: String, value: Array[Byte]): Unit = this.synchronized { + get(key) match { + case arr: ByteArrayNBT if !Arrays.equals(value, arr.getAsByteArray) => delta.putByteArray(key, value) + case _ => + } + super.putByteArray(key, value) } - override def setIntArray(key: String, value: Array[Int]): Unit = this.synchronized { - if (value.deep != getIntArray(key).deep) delta.setIntArray(key, value) - super.setIntArray(key, value) + override def putIntArray(key: String, value: Array[Int]): Unit = this.synchronized { + get(key) match { + case arr: IntArrayNBT if !Arrays.equals(value, arr.getAsIntArray) => delta.putIntArray(key, value) + case _ => + } + super.putIntArray(key, value) } - override def setBoolean(key: String, value: Boolean): Unit = this.synchronized { - if (value != getBoolean(key)) delta.setBoolean(key, value) - super.setBoolean(key, value) + override def putBoolean(key: String, value: Boolean): Unit = this.synchronized { + if (value != getBoolean(key)) delta.putBoolean(key, value) + super.putBoolean(key, value) } } diff --git a/src/main/scala/li/cil/oc/common/container/Printer.scala b/src/main/scala/li/cil/oc/common/container/Printer.scala index 8dbe78c5b8..3be5e425aa 100644 --- a/src/main/scala/li/cil/oc/common/container/Printer.scala +++ b/src/main/scala/li/cil/oc/common/container/Printer.scala @@ -1,13 +1,32 @@ package li.cil.oc.common.container import li.cil.oc.common.Slot +import li.cil.oc.common.Tier +import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.item.ItemStack +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType +import net.minecraft.nbt.CompoundNBT -class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) extends Player(playerInventory, printer) { - addSlotToContainer(18, 19, Slot.Filtered) - addSlotToContainer(18, 51, Slot.Filtered) +class Printer(selfType: ContainerType[_ <: Printer], id: Int, playerInventory: PlayerInventory, val printer: IInventory) + extends Player(selfType, id, playerInventory, printer) { + + override protected def getHostClass = classOf[tileentity.Printer] + + addSlot(new StaticComponentSlot(this, otherInventory, slots.size, 18, 19, getHostClass, Slot.Filtered, Tier.Any) { + override def mayPlace(stack: ItemStack): Boolean = { + if (!container.canPlaceItem(getSlotIndex, stack)) return false + PrintData.materialValue(stack) > 0 + } + }) + addSlot(new StaticComponentSlot(this, otherInventory, slots.size, 18, 51, getHostClass, Slot.Filtered, Tier.Any) { + override def mayPlace(stack: ItemStack): Boolean = { + if (!container.canPlaceItem(getSlotIndex, stack)) return false + PrintData.inkValue(stack) > 0 + } + }) addSlotToContainer(152, 35) // Show the player's inventory. @@ -15,14 +34,25 @@ class Printer(playerInventory: InventoryPlayer, val printer: tileentity.Printer) def progress = synchronizedData.getDouble("progress") - def amountMaterial = synchronizedData.getInteger("amountMaterial") + def maxAmountMaterial = synchronizedData.getInt("maxAmountMaterial") + + def amountMaterial = synchronizedData.getInt("amountMaterial") + + def maxAmountInk = synchronizedData.getInt("maxAmountInk") - def amountInk = synchronizedData.getInteger("amountInk") + def amountInk = synchronizedData.getInt("amountInk") - override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = { - synchronizedData.setDouble("progress", if (printer.isPrinting) printer.progress / 100.0 else 0) - synchronizedData.setInteger("amountMaterial", printer.amountMaterial) - synchronizedData.setInteger("amountInk", printer.amountInk) + override protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { + printer match { + case te: tileentity.Printer => { + synchronizedData.putDouble("progress", if (te.isPrinting) te.progress / 100.0 else 0) + synchronizedData.putInt("maxAmountMaterial", te.maxAmountMaterial) + synchronizedData.putInt("amountMaterial", te.amountMaterial) + synchronizedData.putInt("maxAmountInk", te.maxAmountInk) + synchronizedData.putInt("amountInk", te.amountInk) + } + case _ => + } super.detectCustomDataChanges(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/container/Rack.scala b/src/main/scala/li/cil/oc/common/container/Rack.scala index 7c3fe1900f..a8c470d03d 100644 --- a/src/main/scala/li/cil/oc/common/container/Rack.scala +++ b/src/main/scala/li/cil/oc/common/container/Rack.scala @@ -4,13 +4,20 @@ import li.cil.oc.api.component.RackMountable import li.cil.oc.common.Slot import li.cil.oc.common.tileentity import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagIntArray -import net.minecraft.util.EnumFacing +import li.cil.oc.util.RotationHelper +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.IntArrayNBT +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends Player(playerInventory, rack) { +class Rack(selfType: ContainerType[_ <: Rack], id: Int, playerInventory: PlayerInventory, val rack: IInventory) + extends Player(selfType, id, playerInventory, rack) { + + override protected def getHostClass = classOf[tileentity.Rack] + addSlotToContainer(20, 23, Slot.RackMountable) addSlotToContainer(20, 43, Slot.RackMountable) addSlotToContainer(20, 63, Slot.RackMountable) @@ -19,26 +26,33 @@ class Rack(playerInventory: InventoryPlayer, val rack: tileentity.Rack) extends final val MaxConnections = 4 val nodePresence: Array[Array[Boolean]] = Array.fill(4)(Array.fill(4)(false)) + val nodeMapping: Array[Array[Option[Direction]]] = Array.fill(rack.getContainerSize)(Array.fill[Option[Direction]](4)(None)) + var isRelayEnabled = false - override def updateCustomData(nbt: NBTTagCompound): Unit = { + override def updateCustomData(nbt: CompoundNBT): Unit = { super.updateCustomData(nbt) - nbt.getTagList("nodeMapping", NBT.TAG_INT_ARRAY).map((sides: NBTTagIntArray) => { - sides.getIntArray.map(side => if (side >= 0) Option(EnumFacing.getFront(side)) else None) - }).copyToArray(rack.nodeMapping) + nbt.getList("nodeMapping", NBT.TAG_INT_ARRAY).map((sides: IntArrayNBT) => { + sides.getAsIntArray.map(side => if (side >= 0) Option(Direction.from3DDataValue(side)) else None) + }).copyToArray(nodeMapping) nbt.getBooleanArray("nodePresence").grouped(MaxConnections).copyToArray(nodePresence) - rack.isRelayEnabled = nbt.getBoolean("isRelayEnabled") + isRelayEnabled = nbt.getBoolean("isRelayEnabled") } - override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = { + override protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { super.detectCustomDataChanges(nbt) - nbt.setNewTagList("nodeMapping", rack.nodeMapping.map(sides => toNbt(sides.map { - case Some(side) => side.ordinal() - case _ => -1 - }))) - nbt.setBooleanArray("nodePresence", (0 until rack.getSizeInventory).flatMap(slot => rack.getMountable(slot) match { - case mountable: RackMountable => (Seq(true) ++ (0 until math.min(MaxConnections - 1, mountable.getConnectableCount)).map(index => mountable.getConnectableAt(index) != null)).padTo(MaxConnections, false) - case _ => Array.fill(MaxConnections)(false) - }).toArray) - nbt.setBoolean("isRelayEnabled", rack.isRelayEnabled) + rack match { + case te: tileentity.Rack => { + nbt.setNewTagList("nodeMapping", te.nodeMapping.map(sides => toNbt(sides.map { + case Some(side) => side.ordinal() + case _ => -1 + }))) + nbt.setBooleanArray("nodePresence", (0 until te.getContainerSize).flatMap(slot => te.getMountable(slot) match { + case mountable: RackMountable => (Seq(true) ++ (0 until math.min(MaxConnections - 1, mountable.getConnectableCount)).map(index => mountable.getConnectableAt(index) != null)).padTo(MaxConnections, false) + case _ => Array.fill(MaxConnections)(false) + }).toArray) + nbt.putBoolean("isRelayEnabled", te.isRelayEnabled) + } + case _ => + } } } diff --git a/src/main/scala/li/cil/oc/common/container/Raid.scala b/src/main/scala/li/cil/oc/common/container/Raid.scala index 6774008d7e..06e356f71d 100644 --- a/src/main/scala/li/cil/oc/common/container/Raid.scala +++ b/src/main/scala/li/cil/oc/common/container/Raid.scala @@ -3,9 +3,15 @@ package li.cil.oc.common.container import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType + +class Raid(selfType: ContainerType[_ <: Raid], id: Int, playerInventory: PlayerInventory, raid: IInventory) + extends Player(selfType, id, playerInventory, raid) { + + override protected def getHostClass = classOf[tileentity.Raid] -class Raid(playerInventory: InventoryPlayer, raid: tileentity.Raid) extends Player(playerInventory, raid) { addSlotToContainer(60, 23, Slot.HDD, Tier.Three) addSlotToContainer(80, 23, Slot.HDD, Tier.Three) addSlotToContainer(100, 23, Slot.HDD, Tier.Three) diff --git a/src/main/scala/li/cil/oc/common/container/Relay.scala b/src/main/scala/li/cil/oc/common/container/Relay.scala index d9ee4a54f9..277718d2dd 100644 --- a/src/main/scala/li/cil/oc/common/container/Relay.scala +++ b/src/main/scala/li/cil/oc/common/container/Relay.scala @@ -1,33 +1,59 @@ package li.cil.oc.common.container +import li.cil.oc.Constants +import li.cil.oc.api +import li.cil.oc.api.detail.ItemInfo import li.cil.oc.common.Slot +import li.cil.oc.common.Tier import li.cil.oc.common.tileentity -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.item.ItemStack +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType +import net.minecraft.nbt.CompoundNBT + +class Relay(selfType: ContainerType[_ <: Relay], id: Int, playerInventory: PlayerInventory, relay: IInventory) + extends Player(selfType, id, playerInventory, relay) { + + lazy final val WirelessNetworkCardTier1: ItemInfo = api.Items.get(Constants.ItemName.WirelessNetworkCardTier1) + lazy final val WirelessNetworkCardTier2: ItemInfo = api.Items.get(Constants.ItemName.WirelessNetworkCardTier2) + lazy final val LinkedCard: ItemInfo = api.Items.get(Constants.ItemName.LinkedCard) + + override protected def getHostClass = classOf[tileentity.Relay] -class Relay(playerInventory: InventoryPlayer, relay: tileentity.Relay) extends Player(playerInventory, relay) { addSlotToContainer(151, 15, Slot.CPU) addSlotToContainer(151, 34, Slot.Memory) addSlotToContainer(151, 53, Slot.HDD) - addSlotToContainer(178, 15, Slot.Card) + addSlot(new StaticComponentSlot(this, otherInventory, slots.size, 178, 15, getHostClass, Slot.Card, Tier.Any) { + override def mayPlace(stack: ItemStack): Boolean = { + if (api.Items.get(stack) != WirelessNetworkCardTier1 && api.Items.get(stack) != WirelessNetworkCardTier2 && + api.Items.get(stack) != LinkedCard) return false + super.mayPlace(stack) + } + }) addPlayerInventorySlots(8, 84) - def relayDelay = synchronizedData.getInteger("relayDelay") + def relayDelay = synchronizedData.getInt("relayDelay") - def relayAmount = synchronizedData.getInteger("relayAmount") + def relayAmount = synchronizedData.getInt("relayAmount") - def maxQueueSize = synchronizedData.getInteger("maxQueueSize") + def maxQueueSize = synchronizedData.getInt("maxQueueSize") - def packetsPerCycleAvg = synchronizedData.getInteger("packetsPerCycleAvg") + def packetsPerCycleAvg = synchronizedData.getInt("packetsPerCycleAvg") - def queueSize = synchronizedData.getInteger("queueSize") + def queueSize = synchronizedData.getInt("queueSize") - override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = { - synchronizedData.setInteger("relayDelay", relay.relayDelay) - synchronizedData.setInteger("relayAmount", relay.relayAmount) - synchronizedData.setInteger("maxQueueSize", relay.maxQueueSize) - synchronizedData.setInteger("packetsPerCycleAvg", relay.packetsPerCycleAvg()) - synchronizedData.setInteger("queueSize", relay.queue.size) + override protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { + relay match { + case te: tileentity.Relay => { + synchronizedData.putInt("relayDelay", te.relayDelay) + synchronizedData.putInt("relayAmount", te.relayAmount) + synchronizedData.putInt("maxQueueSize", te.maxQueueSize) + synchronizedData.putInt("packetsPerCycleAvg", te.packetsPerCycleAvg()) + synchronizedData.putInt("queueSize", te.queue.size) + } + case _ => + } super.detectCustomDataChanges(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/container/Robot.scala b/src/main/scala/li/cil/oc/common/container/Robot.scala index 4d73cb09a7..7bab9f8c50 100644 --- a/src/main/scala/li/cil/oc/common/container/Robot.scala +++ b/src/main/scala/li/cil/oc/common/container/Robot.scala @@ -3,39 +3,115 @@ package li.cil.oc.common.container import li.cil.oc.api import li.cil.oc.client.Textures import li.cil.oc.common +import li.cil.oc.common.ComponentTracker import li.cil.oc.common.tileentity +import li.cil.oc.integration.opencomputers.DriverKeyboard +import li.cil.oc.integration.opencomputers.DriverScreen import li.cil.oc.util.SideTracker -import net.minecraft.entity.player.InventoryPlayer +import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType import net.minecraft.item.ItemStack +import net.minecraft.network.PacketBuffer +import net.minecraft.world.World +import net.minecraft.util.IntReferenceHolder import net.minecraft.util.ResourceLocation -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends Player(playerInventory, robot) { - val hasScreen: Boolean = robot.components.exists { - case Some(buffer: api.internal.TextBuffer) => true - case _ => false +object RobotInfo { + def getScreenBuffer(robot: tileentity.Robot): Option[String] = robot.components.collectFirst { + case Some(buffer: api.internal.TextBuffer) if buffer.node != null => buffer.node.address } + + def hasKeyboard(robot: tileentity.Robot) = robot.info.components.map(api.Driver.driverFor(_, robot.getClass)).contains(DriverKeyboard) + + def readRobotInfo(buff: PacketBuffer): RobotInfo = { + val mainInvSize = buff.readVarInt() + val slot1 = buff.readUtf(32) + val tier1 = buff.readVarInt() + val slot2 = buff.readUtf(32) + val tier2 = buff.readVarInt() + val slot3 = buff.readUtf(32) + val tier3 = buff.readVarInt() + val screenBuffer = buff.readBoolean() match { + case true => Some(buff.readUtf()) + case false => None + } + val hasKeyboard = buff.readBoolean() + new RobotInfo(mainInvSize, slot1, tier1, slot2, tier2, slot3, tier3, screenBuffer, hasKeyboard) + } + + def writeRobotInfo(buff: PacketBuffer, info: RobotInfo) { + buff.writeVarInt(info.mainInvSize) + buff.writeUtf(info.slot1, 32) + buff.writeVarInt(info.tier1) + buff.writeUtf(info.slot2, 32) + buff.writeVarInt(info.tier2) + buff.writeUtf(info.slot3, 32) + buff.writeVarInt(info.tier3) + info.screenBuffer match { + case Some(addr) => { + buff.writeBoolean(true) + buff.writeUtf(addr) + } + case _ => buff.writeBoolean(false) + } + buff.writeBoolean(info.hasKeyboard) + } +} + +class RobotInfo(val mainInvSize: Int, val slot1: String, val tier1: Int, + val slot2: String, val tier2: Int, val slot3: String, val tier3: Int, + val screenBuffer: Option[String], val hasKeyboard: Boolean) { + + def this(robot: tileentity.Robot) = this(robot.mainInventory.getContainerSize, robot.containerSlotType(1), robot.containerSlotTier(1), + robot.containerSlotType(2), robot.containerSlotTier(2), robot.containerSlotType(3), robot.containerSlotTier(3), + RobotInfo.getScreenBuffer(robot), RobotInfo.hasKeyboard(robot)) +} + +class Robot(selfType: ContainerType[_ <: Robot], id: Int, playerInventory: PlayerInventory, robot: IInventory, val info: RobotInfo) + extends Player(selfType, id, playerInventory, robot) { + private val withScreenHeight = 256 private val noScreenHeight = 108 - val deltaY: Int = if (hasScreen) 0 else withScreenHeight - noScreenHeight + val deltaY: Int = if (info.screenBuffer.isDefined) 0 else withScreenHeight - noScreenHeight + + override protected def getHostClass = classOf[tileentity.Robot] addSlotToContainer(170 + 0 * slotSize, 232 - deltaY, common.Slot.Tool) - addSlotToContainer(170 + 1 * slotSize, 232 - deltaY, robot.containerSlotType(1), robot.containerSlotTier(1)) - addSlotToContainer(170 + 2 * slotSize, 232 - deltaY, robot.containerSlotType(2), robot.containerSlotTier(2)) - addSlotToContainer(170 + 3 * slotSize, 232 - deltaY, robot.containerSlotType(3), robot.containerSlotTier(3)) - - for (i <- 0 to 3) { - val y = 156 + i * slotSize - deltaY - for (j <- 0 to 3) { - val x = 170 + j * slotSize - addSlotToContainer(new InventorySlot(this, otherInventory, inventorySlots.size, x, y)) - } + addSpecialSlot(170 + 1 * slotSize, 232 - deltaY, info.slot1, info.tier1) + addSpecialSlot(170 + 2 * slotSize, 232 - deltaY, info.slot2, info.tier2) + addSpecialSlot(170 + 3 * slotSize, 232 - deltaY, info.slot3, info.tier3) + + // Like addSlotToContainer, but handles the very special, much edge case with screen & keyboard. + def addSpecialSlot(x: Int, y: Int, slot: String, tier: Int) { + val index = slots.size + addSlot(new StaticComponentSlot(this, otherInventory, index, x, y, getHostClass, slot, tier) { + override def mayPlace(stack: ItemStack): Boolean = { + if (DriverScreen.worksWith(stack, getHostClass)) return false + if (DriverKeyboard.worksWith(stack, getHostClass)) return false + super.mayPlace(stack) + } + }) } - for (i <- 16 until 64) { - addSlotToContainer(new InventorySlot(this, otherInventory, inventorySlots.size, -10000, -10000)) + + // Slot.x and Slot.y are final, so have to rebuild when scrolling + def generateSlotsFor(scroll: Int) { + val maxRows = math.max(info.mainInvSize / 4, 4) + for (i <- 0 until maxRows) { + val y = 156 + (i - scroll) * slotSize - deltaY + for (j <- 0 to 3) { + val x = 170 + j * slotSize + val idx = 4 + j + 4 * i + val slot = new InventorySlot(this, otherInventory, idx, x, y, i >= scroll && i < scroll + 4) + slot.index = idx + if (slots.size() <= idx) addSlot(slot) + else slots.set(idx, slot) + } + } } + generateSlotsFor(0) addPlayerInventorySlots(6, 174 - deltaY) @@ -44,51 +120,69 @@ class Robot(playerInventory: InventoryPlayer, robot: tileentity.Robot) extends P // values as shorts over the net (for whatever reason). private val factor = 100 - private var lastSentBuffer = -1 + private val globalBufferData = robot match { + case te: tileentity.Robot => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = te.globalBuffer.toInt / factor - private var lastSentBufferSize = -1 + override def set(value: Int): Unit = te.globalBuffer = value * factor + }) + } + case _ => addDataSlot(IntReferenceHolder.standalone) + } + def globalBuffer = globalBufferData.get * factor - @SideOnly(Side.CLIENT) - override def updateProgressBar(id: Int, value: Int) { - super.updateProgressBar(id, value) - if (id == 0) { - robot.globalBuffer = value * factor + private val globalBufferSizeData = robot match { + case te: tileentity.Robot => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = te.globalBufferSize.toInt / factor + + override def set(value: Int): Unit = te.globalBufferSize = value * factor + }) } + case _ => addDataSlot(IntReferenceHolder.standalone) + } + def globalBufferSize = globalBufferSizeData.get * factor + + private val runningData = robot match { + case te: tileentity.Robot => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = if (te.isRunning) 1 else 0 - if (id == 1) { - robot.globalBufferSize = value * factor + override def set(value: Int): Unit = te.setRunning(value != 0) + }) } + case _ => addDataSlot(IntReferenceHolder.standalone) } + def isRunning = runningData.get != 0 - override def detectAndSendChanges() { - super.detectAndSendChanges() - if (SideTracker.isServer) { - val currentBuffer = robot.globalBuffer.toInt / factor - if (currentBuffer != lastSentBuffer) { - lastSentBuffer = currentBuffer - sendWindowProperty(0, lastSentBuffer) - } + private val selectedSlotData = robot match { + case te: tileentity.Robot => { + addDataSlot(new IntReferenceHolder { + override def get(): Int = te.selectedSlot - val currentBufferSize = robot.globalBufferSize.toInt / factor - if (currentBufferSize != lastSentBufferSize) { - lastSentBufferSize = currentBufferSize - sendWindowProperty(1, lastSentBufferSize) - } + override def set(value: Int): Unit = te.setSelectedSlot(value) + }) } + case _ => addDataSlot(IntReferenceHolder.standalone) } + def selectedSlot = selectedSlotData.get + + class InventorySlot(container: Player, inventory: IInventory, index: Int, x: Int, y: Int, enabled: Boolean) + extends StaticComponentSlot(container, inventory, index, x, y, getHostClass, common.Slot.Any, common.Tier.Any) { - class InventorySlot(container: Player, inventory: IInventory, index: Int, x: Int, y: Int) extends StaticComponentSlot(container, inventory, index, x, y, common.Slot.Any, common.Tier.Any) { - def isValid: Boolean = robot.isInventorySlot(getSlotIndex) + def isValid: Boolean = getSlotIndex >= 4 && getSlotIndex < 4 + info.mainInvSize - @SideOnly(Side.CLIENT) override - def isEnabled: Boolean = isValid && super.isEnabled + @OnlyIn(Dist.CLIENT) override + def isActive: Boolean = enabled && isValid && super.isActive + @OnlyIn(Dist.CLIENT) override def getBackgroundLocation: ResourceLocation = if (isValid) super.getBackgroundLocation else Textures.Icons.get(common.Tier.None) - override def getStack: ItemStack = { - if (isValid) super.getStack + override def getItem: ItemStack = { + if (isValid) super.getItem else ItemStack.EMPTY } } diff --git a/src/main/scala/li/cil/oc/common/container/Server.scala b/src/main/scala/li/cil/oc/common/container/Server.scala index 19700b379f..27d2826e35 100644 --- a/src/main/scala/li/cil/oc/common/container/Server.scala +++ b/src/main/scala/li/cil/oc/common/container/Server.scala @@ -3,64 +3,73 @@ package li.cil.oc.common.container import li.cil.oc.common.InventorySlots import li.cil.oc.common.inventory.ServerInventory import li.cil.oc.server.component -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType +import net.minecraft.item.ItemStack +import net.minecraft.nbt.CompoundNBT + +class Server(selfType: ContainerType[_ <: Server], id: Int, playerInventory: PlayerInventory, val stack: ItemStack, serverInventory: IInventory, tier: Int, val rackSlot: Int) + extends Player(selfType, id, playerInventory, serverInventory) { + + override protected def getHostClass = classOf[component.Server] -class Server(playerInventory: InventoryPlayer, serverInventory: ServerInventory, val server: Option[component.Server] = None) extends Player(playerInventory, serverInventory) { for (i <- 0 to 1) { - val slot = InventorySlots.server(serverInventory.tier)(getInventory.size) + val slot = InventorySlots.server(tier)(slots.size) addSlotToContainer(76, 7 + i * slotSize, slot.slot, slot.tier) } - val verticalSlots = math.min(3, 1 + serverInventory.tier) + val verticalSlots = math.min(3, 1 + tier) for (i <- 0 to verticalSlots) { - val slot = InventorySlots.server(serverInventory.tier)(getInventory.size) + val slot = InventorySlots.server(tier)(slots.size) addSlotToContainer(100, 7 + i * slotSize, slot.slot, slot.tier) } for (i <- 0 to verticalSlots) { - val slot = InventorySlots.server(serverInventory.tier)(getInventory.size) + val slot = InventorySlots.server(tier)(slots.size) addSlotToContainer(124, 7 + i * slotSize, slot.slot, slot.tier) } for (i <- 0 to verticalSlots) { - val slot = InventorySlots.server(serverInventory.tier)(getInventory.size) + val slot = InventorySlots.server(tier)(slots.size) addSlotToContainer(148, 7 + i * slotSize, slot.slot, slot.tier) } for (i <- 2 to verticalSlots) { - val slot = InventorySlots.server(serverInventory.tier)(getInventory.size) + val slot = InventorySlots.server(tier)(slots.size) addSlotToContainer(76, 7 + i * slotSize, slot.slot, slot.tier) } { - val slot = InventorySlots.server(serverInventory.tier)(getInventory.size) + val slot = InventorySlots.server(tier)(slots.size) addSlotToContainer(26, 34, slot.slot, slot.tier) } // Show the player's inventory. addPlayerInventorySlots(8, 84) - override def canInteractWith(player: EntityPlayer) = { - if (server.isDefined) super.canInteractWith(player) - else player == playerInventory.player + override def stillValid(player: PlayerEntity) = { + otherInventory match { + case _: component.Server => super.stillValid(player) + case _ => player == playerInventory.player + } } var isRunning = false var isItem = true - override def updateCustomData(nbt: NBTTagCompound): Unit = { + override def updateCustomData(nbt: CompoundNBT): Unit = { super.updateCustomData(nbt) isRunning = nbt.getBoolean("isRunning") isItem = nbt.getBoolean("isItem") } - override protected def detectCustomDataChanges(nbt: NBTTagCompound): Unit = { + override protected def detectCustomDataChanges(nbt: CompoundNBT): Unit = { super.detectCustomDataChanges(nbt) - server match { - case Some(s) => nbt.setBoolean("isRunning", s.machine.isRunning) - case _ => nbt.setBoolean("isItem", true) + otherInventory match { + case s: component.Server => nbt.putBoolean("isRunning", s.machine.isRunning) + case _ => nbt.putBoolean("isItem", true) } } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/container/StaticComponentSlot.scala b/src/main/scala/li/cil/oc/common/container/StaticComponentSlot.scala index 412c6dabed..d9180fe6cb 100644 --- a/src/main/scala/li/cil/oc/common/container/StaticComponentSlot.scala +++ b/src/main/scala/li/cil/oc/common/container/StaticComponentSlot.scala @@ -1,19 +1,25 @@ package li.cil.oc.common.container +import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.client.Textures import li.cil.oc.common import net.minecraft.inventory.IInventory +import net.minecraft.util.ResourceLocation +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -class StaticComponentSlot(val container: Player, inventory: IInventory, index: Int, x: Int, y: Int, val slot: String, val tier: Int) extends ComponentSlot(inventory, index, x, y) { - if (container.playerInventory.player.getEntityWorld.isRemote) { - setBackgroundLocation(Textures.Icons.get(slot)) - } +class StaticComponentSlot(val agentContainer: Player, inventory: IInventory, index: Int, x: Int, y: Int, host: Class[_ <: EnvironmentHost], val slot: String, val tier: Int) + extends ComponentSlot(inventory, index, x, y, host) { - val tierIcon = Textures.Icons.get(tier) + @OnlyIn(Dist.CLIENT) + def tierIcon = Textures.Icons.get(tier) - override def getSlotStackLimit = + @OnlyIn(Dist.CLIENT) + override def getBackgroundLocation: ResourceLocation = Textures.Icons.get(slot) + + override def getMaxStackSize = slot match { - case common.Slot.Tool | common.Slot.Any | common.Slot.Filtered => super.getSlotStackLimit + case common.Slot.Tool | common.Slot.Any | common.Slot.Filtered => super.getMaxStackSize case common.Slot.None => 0 case _ => 1 } diff --git a/src/main/scala/li/cil/oc/common/container/Tablet.scala b/src/main/scala/li/cil/oc/common/container/Tablet.scala index 5e84bd3479..f00ff4ff80 100644 --- a/src/main/scala/li/cil/oc/common/container/Tablet.scala +++ b/src/main/scala/li/cil/oc/common/container/Tablet.scala @@ -1,13 +1,26 @@ package li.cil.oc.common.container import li.cil.oc.common.item.TabletWrapper -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.InventoryPlayer +import li.cil.oc.integration.opencomputers.DriverScreen +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.ContainerType +import net.minecraft.item.ItemStack -class Tablet(playerInventory: InventoryPlayer, tablet: TabletWrapper) extends Player(playerInventory, tablet) { - addSlotToContainer(new StaticComponentSlot(this, otherInventory, otherInventory.getSizeInventory - 1, 80, 35, tablet.containerSlotType, tablet.containerSlotTier)) +class Tablet(selfType: ContainerType[_ <: Tablet], id: Int, playerInventory: PlayerInventory, val stack: ItemStack, tablet: IInventory, slot1: String, tier1: Int) + extends Player(selfType, id, playerInventory, tablet) { + + override protected def getHostClass = classOf[TabletWrapper] + + addSlot(new StaticComponentSlot(this, otherInventory, otherInventory.getContainerSize - 1, 80, 35, getHostClass, slot1, tier1) { + override def mayPlace(stack: ItemStack): Boolean = { + if (DriverScreen.worksWith(stack, getHostClass)) return false + super.mayPlace(stack) + } + }) addPlayerInventorySlots(8, 84) - override def canInteractWith(player: EntityPlayer) = player == playerInventory.player + override def stillValid(player: PlayerEntity) = player == playerInventory.player } diff --git a/src/main/scala/li/cil/oc/common/entity/Drone.scala b/src/main/scala/li/cil/oc/common/entity/Drone.scala index 552fbd817d..b2ccae8634 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -19,7 +19,8 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.machine.MachineHost import li.cil.oc.api.network._ import li.cil.oc.common.EventHandler -import li.cil.oc.common.GuiType +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.inventory.ComponentInventory import li.cil.oc.common.inventory.Inventory import li.cil.oc.common.item.data.DroneData @@ -30,45 +31,62 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.InventoryUtils -import net.minecraft.block.Block +import net.minecraft.block.BlockState import net.minecraft.block.material.Material import net.minecraft.entity.Entity +import net.minecraft.entity.EntitySize +import net.minecraft.entity.EntityType import net.minecraft.entity.MoverType -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.Pose +import net.minecraft.entity.item.ItemEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.network.datasync.DataParameter import net.minecraft.network.datasync.DataSerializers import net.minecraft.network.datasync.EntityDataManager -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.tags.FluidTags +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Vec3d +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import net.minecraftforge.fluids.IFluidTank +import net.minecraftforge.fml.network.NetworkHooks -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ object Drone { - val DataRunning: DataParameter[lang.Boolean] = EntityDataManager.createKey(classOf[Drone], DataSerializers.BOOLEAN) - val DataTargetX: DataParameter[lang.Float] = EntityDataManager.createKey(classOf[Drone], DataSerializers.FLOAT) - val DataTargetY: DataParameter[lang.Float] = EntityDataManager.createKey(classOf[Drone], DataSerializers.FLOAT) - val DataTargetZ: DataParameter[lang.Float] = EntityDataManager.createKey(classOf[Drone], DataSerializers.FLOAT) - val DataMaxAcceleration: DataParameter[lang.Float] = EntityDataManager.createKey(classOf[Drone], DataSerializers.FLOAT) - val DataSelectedSlot: DataParameter[Integer] = EntityDataManager.createKey(classOf[Drone], DataSerializers.VARINT) - val DataCurrentEnergy: DataParameter[Integer] = EntityDataManager.createKey(classOf[Drone], DataSerializers.VARINT) - val DataMaxEnergy: DataParameter[Integer] = EntityDataManager.createKey(classOf[Drone], DataSerializers.VARINT) - val DataStatusText: DataParameter[String] = EntityDataManager.createKey(classOf[Drone], DataSerializers.STRING) - val DataInventorySize: DataParameter[Integer] = EntityDataManager.createKey(classOf[Drone], DataSerializers.VARINT) - val DataLightColor: DataParameter[Integer] = EntityDataManager.createKey(classOf[Drone], DataSerializers.VARINT) + val DataRunning: DataParameter[lang.Boolean] = EntityDataManager.defineId(classOf[Drone], DataSerializers.BOOLEAN) + val DataTargetX: DataParameter[lang.Float] = EntityDataManager.defineId(classOf[Drone], DataSerializers.FLOAT) + val DataTargetY: DataParameter[lang.Float] = EntityDataManager.defineId(classOf[Drone], DataSerializers.FLOAT) + val DataTargetZ: DataParameter[lang.Float] = EntityDataManager.defineId(classOf[Drone], DataSerializers.FLOAT) + val DataMaxAcceleration: DataParameter[lang.Float] = EntityDataManager.defineId(classOf[Drone], DataSerializers.FLOAT) + val DataSelectedSlot: DataParameter[Integer] = EntityDataManager.defineId(classOf[Drone], DataSerializers.INT) + val DataCurrentEnergy: DataParameter[Integer] = EntityDataManager.defineId(classOf[Drone], DataSerializers.INT) + val DataMaxEnergy: DataParameter[Integer] = EntityDataManager.defineId(classOf[Drone], DataSerializers.INT) + val DataStatusText: DataParameter[String] = EntityDataManager.defineId(classOf[Drone], DataSerializers.STRING) + val DataInventorySize: DataParameter[Integer] = EntityDataManager.defineId(classOf[Drone], DataSerializers.INT) + val DataLightColor: DataParameter[Integer] = EntityDataManager.defineId(classOf[Drone], DataSerializers.INT) } +abstract class DroneInventory(val drone: Drone) extends Inventory + // internal.Rotatable is also in internal.Drone, but it wasn't since the start // so this is to ensure it is implemented here, in the very unlikely case that // someone decides to ship that specific version of the API. -class Drone(world: World) extends Entity(world) with MachineHost with internal.Drone with internal.Rotatable with Analyzable with Context { - override def world: World = getEntityWorld +class Drone(selfType: EntityType[Drone], world: World) extends Entity(selfType, world) with MachineHost with internal.Drone with internal.Rotatable with Analyzable with Context { + override def world: World = level // Some basic constants. val gravity = 0.05f @@ -77,8 +95,6 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D val maxAcceleration = 0.1f val maxVelocity = 0.4f val maxInventorySize = 8 - setSize(12 / 16f, 6 / 16f) - isImmuneToFire = true // Rendering stuff, purely eyecandy. val targetFlapAngles: Array[Array[Float]] = Array.fill(4, 2)(0f) @@ -91,24 +107,24 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D // Logic stuff, components, machine and such. val info = new DroneData() - val machine: api.machine.Machine = if (!world.isRemote) { + val machine: api.machine.Machine = if (!world.isClientSide) { val m = Machine.create(this) m.node.asInstanceOf[Connector].setLocalBufferSize(0) m } else null - val control: component.Drone = if (!world.isRemote) new component.Drone(this) else null + val control: component.Drone = if (!world.isClientSide) new component.Drone(this) else null val components = new ComponentInventory { override def host: Drone = Drone.this override def items: Array[ItemStack] = info.components - override def getSizeInventory: Int = info.components.length + override def getContainerSize: Int = info.components.length - override def markDirty() {} + override def setChanged() {} - override def isItemValidForSlot(slot: Int, stack: ItemStack) = true + override def canPlaceItem(slot: Int, stack: ItemStack) = true - override def isUsableByPlayer(player: EntityPlayer) = true + override def stillValid(player: PlayerEntity) = true override def node: Node = Option(machine).map(_.node).orNull @@ -121,28 +137,28 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D val equipmentInventory = new Inventory { val items = Array.empty[ItemStack] - override def getSizeInventory = 0 + override def getContainerSize = 0 - override def getInventoryStackLimit = 0 + override def getMaxStackSize = 0 - override def markDirty(): Unit = {} + override def setChanged(): Unit = {} - override def isItemValidForSlot(slot: Int, stack: ItemStack) = false + override def canPlaceItem(slot: Int, stack: ItemStack) = false - override def isUsableByPlayer(player: EntityPlayer) = false + override def stillValid(player: PlayerEntity) = false } - val mainInventory = new Inventory { + val mainInventory = new DroneInventory(this) { val items: Array[ItemStack] = Array.fill[ItemStack](8)(ItemStack.EMPTY) - override def getSizeInventory: Int = inventorySize + override def getContainerSize: Int = inventorySize - override def getInventoryStackLimit = 64 + override def getMaxStackSize = 64 - override def markDirty() {} // TODO update client GUI? + override def setChanged() {} // TODO update client GUI? - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = slot >= 0 && slot < getSizeInventory + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = slot >= 0 && slot < getContainerSize - override def isUsableByPlayer(player: EntityPlayer): Boolean = player.getDistanceSq(Drone.this) < 64 + override def stillValid(player: PlayerEntity): Boolean = player.distanceToSqr(drone) < 64 } val tank = new MultiTank { override def tankCount: Int = components.components.count { @@ -160,9 +176,9 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D override def tier: Int = info.tier - override def player(): EntityPlayer = { + override def player(): PlayerEntity = { agent.Player.updatePositionAndRotation(player_, facing, facing) - agent.Player.setInventoryPlayerItems(player_) + agent.Player.setPlayerInventoryItems(player_) player_ } @@ -187,7 +203,7 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D override def isPaused: Boolean = machine.isPaused override def start(): Boolean = { - if (world.isRemote || machine.isRunning) { + if (world.isClientSide || machine.isRunning) { return false } preparePowerUp() @@ -204,43 +220,47 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D // ----------------------------------------------------------------------- // - override def getTarget = new Vec3d(targetX.floatValue(), targetY.floatValue(), targetZ.floatValue()) + override def getTarget = new Vector3d(targetX.floatValue(), targetY.floatValue(), targetZ.floatValue()) - override def setTarget(value: Vec3d): Unit = { + override def setTarget(value: Vector3d): Unit = { targetX = value.x.toFloat targetY = value.y.toFloat targetZ = value.z.toFloat } - override def getVelocity = new Vec3d(motionX, motionY, motionZ) + override def getVelocity = getDeltaMovement // ----------------------------------------------------------------------- // - override def canBeCollidedWith = true + override def isPickable = true - override def canBePushed = true + override def isPushable = true // ----------------------------------------------------------------------- // - override def xPosition: Double = posX + override def xPosition: Double = getX - override def yPosition: Double = posY + override def yPosition: Double = getY - override def zPosition: Double = posZ + override def zPosition: Double = getZ override def markChanged() {} + @OnlyIn(Dist.CLIENT) + override def getRopeHoldPosition(dt: Float): Vector3d = + getPosition(dt).add(0.0, -0.056, 0.0) // Offset: height * 0.85 * 0.7 - 0.25 + // ----------------------------------------------------------------------- // - override def facing = EnumFacing.SOUTH + override def facing = Direction.SOUTH - override def toLocal(value: EnumFacing): EnumFacing = value + override def toLocal(value: Direction): Direction = value - override def toGlobal(value: EnumFacing): EnumFacing = value + override def toGlobal(value: Direction): Direction = value // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) // ----------------------------------------------------------------------- // @@ -262,32 +282,32 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D // ----------------------------------------------------------------------- // - override def entityInit() { - getDataManager.register(Drone.DataRunning, java.lang.Boolean.FALSE) - getDataManager.register(Drone.DataTargetX, Float.box(0f)) - getDataManager.register(Drone.DataTargetY, Float.box(0f)) - getDataManager.register(Drone.DataTargetZ, Float.box(0f)) - getDataManager.register(Drone.DataMaxAcceleration, Float.box(0f)) - getDataManager.register(Drone.DataSelectedSlot, Int.box(0)) - getDataManager.register(Drone.DataCurrentEnergy, Int.box(0)) - getDataManager.register(Drone.DataMaxEnergy, Int.box(100)) - getDataManager.register(Drone.DataStatusText, "") - getDataManager.register(Drone.DataInventorySize, Int.box(0)) - getDataManager.register(Drone.DataLightColor, Int.box(0x66DD55)) + override def defineSynchedData() { + entityData.define(Drone.DataRunning, java.lang.Boolean.FALSE) + entityData.define(Drone.DataTargetX, Float.box(0f)) + entityData.define(Drone.DataTargetY, Float.box(0f)) + entityData.define(Drone.DataTargetZ, Float.box(0f)) + entityData.define(Drone.DataMaxAcceleration, Float.box(0f)) + entityData.define(Drone.DataSelectedSlot, Int.box(0)) + entityData.define(Drone.DataCurrentEnergy, Int.box(0)) + entityData.define(Drone.DataMaxEnergy, Int.box(100)) + entityData.define(Drone.DataStatusText, "") + entityData.define(Drone.DataInventorySize, Int.box(0)) + entityData.define(Drone.DataLightColor, Int.box(0x66DD55)) } - def initializeAfterPlacement(stack: ItemStack, player: EntityPlayer, position: Vec3d) { - info.load(stack) + def initializeAfterPlacement(stack: ItemStack, player: PlayerEntity, position: Vector3d) { + info.loadData(stack) control.node.changeBuffer(info.storedEnergy - control.node.localBuffer) wireThingsTogether() inventorySize = computeInventorySize() - setPosition(position.x, position.y, position.z) + setPos(position.x, position.y, position.z) } def preparePowerUp() { - targetX = math.floor(posX).toFloat + 0.5f - targetY = math.round(posY).toFloat + 0.5f - targetZ = math.floor(posZ).toFloat + 0.5f + targetX = math.floor(getX).toFloat + 0.5f + targetY = math.round(getY).toFloat + 0.5f + targetZ = math.floor(getZ).toFloat + 0.5f targetAcceleration = maxAcceleration wireThingsTogether() @@ -300,57 +320,57 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D components.connectComponents() } - def isRunning: Boolean = getDataManager.get(Drone.DataRunning) + def isRunning: Boolean = entityData.get(Drone.DataRunning) - def targetX: lang.Float = getDataManager.get(Drone.DataTargetX) + def targetX: lang.Float = entityData.get(Drone.DataTargetX) - def targetY: lang.Float = getDataManager.get(Drone.DataTargetY) + def targetY: lang.Float = entityData.get(Drone.DataTargetY) - def targetZ: lang.Float = getDataManager.get(Drone.DataTargetZ) + def targetZ: lang.Float = entityData.get(Drone.DataTargetZ) - def targetAcceleration: lang.Float = getDataManager.get(Drone.DataMaxAcceleration) + def targetAcceleration: lang.Float = entityData.get(Drone.DataMaxAcceleration) - def selectedSlot: Int = getDataManager.get(Drone.DataSelectedSlot) & 0xFF + def selectedSlot: Int = entityData.get(Drone.DataSelectedSlot) & 0xFF - def globalBuffer: Integer = getDataManager.get(Drone.DataCurrentEnergy) + def globalBuffer: Integer = entityData.get(Drone.DataCurrentEnergy) - def globalBufferSize: Integer = getDataManager.get(Drone.DataMaxEnergy) + def globalBufferSize: Integer = entityData.get(Drone.DataMaxEnergy) - def statusText: String = getDataManager.get(Drone.DataStatusText) + def statusText: String = entityData.get(Drone.DataStatusText) - def inventorySize: Int = getDataManager.get(Drone.DataInventorySize) & 0xFF + def inventorySize: Int = entityData.get(Drone.DataInventorySize) & 0xFF - def lightColor: Integer = getDataManager.get(Drone.DataLightColor) + def lightColor: Integer = entityData.get(Drone.DataLightColor) - def setRunning(value: Boolean): Unit = getDataManager.set(Drone.DataRunning, Boolean.box(value)) + def setRunning(value: Boolean): Unit = entityData.set(Drone.DataRunning, Boolean.box(value)) // Round target values to low accuracy to avoid floating point errors accumulating. - def targetX_=(value: Float): Unit = getDataManager.set(Drone.DataTargetX, Float.box(math.round(value * 4) / 4f)) + def targetX_=(value: Float): Unit = entityData.set(Drone.DataTargetX, Float.box(math.round(value * 4) / 4f)) - def targetY_=(value: Float): Unit = getDataManager.set(Drone.DataTargetY, Float.box(math.round(value * 4) / 4f)) + def targetY_=(value: Float): Unit = entityData.set(Drone.DataTargetY, Float.box(math.round(value * 4) / 4f)) - def targetZ_=(value: Float): Unit = getDataManager.set(Drone.DataTargetZ, Float.box(math.round(value * 4) / 4f)) + def targetZ_=(value: Float): Unit = entityData.set(Drone.DataTargetZ, Float.box(math.round(value * 4) / 4f)) - def targetAcceleration_=(value: Float): Unit = getDataManager.set(Drone.DataMaxAcceleration, Float.box(math.max(0, math.min(maxAcceleration, value)))) + def targetAcceleration_=(value: Float): Unit = entityData.set(Drone.DataMaxAcceleration, Float.box(math.max(0, math.min(maxAcceleration, value)))) - def setSelectedSlot(value: Int): Unit = getDataManager.set(Drone.DataSelectedSlot, Int.box(value.toByte)) + def setSelectedSlot(value: Int): Unit = entityData.set(Drone.DataSelectedSlot, Int.box(value.toByte)) - def globalBuffer_=(value: Int): Unit = getDataManager.set(Drone.DataCurrentEnergy, Int.box(value)) + def globalBuffer_=(value: Int): Unit = entityData.set(Drone.DataCurrentEnergy, Int.box(value)) - def globalBufferSize_=(value: Int): Unit = getDataManager.set(Drone.DataMaxEnergy, Int.box(value)) + def globalBufferSize_=(value: Int): Unit = entityData.set(Drone.DataMaxEnergy, Int.box(value)) - def statusText_=(value: String): Unit = getDataManager.set(Drone.DataStatusText, Option(value).fold("")(_.lines.map(_.take(10)).take(2).mkString("\n"))) + def statusText_=(value: String): Unit = entityData.set(Drone.DataStatusText, Option(value).fold("")(_.lines.map(_.take(10)).take(2).mkString("\n"))) - def inventorySize_=(value: Int): Unit = getDataManager.set(Drone.DataInventorySize, Int.box(value.toByte)) + def inventorySize_=(value: Int): Unit = entityData.set(Drone.DataInventorySize, Int.box(value.toByte)) - def lightColor_=(value: Int): Unit = getDataManager.set(Drone.DataLightColor, Int.box(value)) + def lightColor_=(value: Int): Unit = entityData.set(Drone.DataLightColor, Int.box(value)) - override def setPositionAndRotationDirect(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, posRotationIncrements: Int, teleport: Boolean): Unit = { + override def lerpTo(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, posRotationIncrements: Int, teleport: Boolean): Unit = { // Only set exact position if we're too far away from the server's // position, otherwise keep interpolating. This removes jitter and // is good enough for drones. - if (!isRunning || getDistanceSq(x, y, z) > 1) { - super.setPositionAndRotation(x, y, z, yaw, pitch) + if (!isRunning || distanceToSqr(x, y, z) > 1) { + super.absMoveTo(x, y, z, yaw, pitch) } else { targetX = x.toFloat @@ -359,11 +379,11 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D } } - override def onUpdate() { - super.onUpdate() + override def tick() { + super.tick() - if (!world.isRemote) { - if (isInsideOfMaterial(Material.WATER) || isInsideOfMaterial(Material.LAVA)) { + if (!world.isClientSide) { + if (isInWater || isInLava) { // We're not water-proof! machine.stop() } @@ -372,7 +392,7 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D setRunning(machine.isRunning) val buffer = math.round(machine.node.asInstanceOf[Connector].globalBuffer).toInt - if (math.abs(lastEnergyUpdate - buffer) > 1 || world.getTotalWorldTime % 200 == 0) { + if (math.abs(lastEnergyUpdate - buffer) > 1 || world.getGameTime % 200 == 0) { lastEnergyUpdate = buffer globalBuffer = buffer globalBufferSize = machine.node.asInstanceOf[Connector].globalBufferSize.toInt @@ -382,7 +402,7 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D if (isRunning) { // Client side update; occasionally update wing pitch and rotation to // make the drones look a bit more dynamic. - val rng = world.rand + val rng = world.random nextFlapChange -= 1 nextAngularVelocityChange -= 1 @@ -417,137 +437,134 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D } } - prevPosX = posX - prevPosY = posY - prevPosZ = posZ - noClip = pushOutOfBlocks(posX, (getEntityBoundingBox.minY + getEntityBoundingBox.maxY) / 2, posZ) + xo = getX + yo = getY + zo = getZ + noPhysics = !level.noCollision(this) + if (noPhysics) moveTowardsClosestSpace(getX, (getBoundingBox.minY + getBoundingBox.maxY) / 2, getZ) if (isRunning) { - val toTarget = new Vec3d(targetX - posX, targetY - posY, targetZ - posZ) - val distance = toTarget.lengthVector() - val velocity = new Vec3d(motionX, motionY, motionZ) - if (distance > 0 && (distance > 0.005f || velocity.dotProduct(velocity) > 0.005f)) { + val toTarget = new Vector3d(targetX - getX, targetY - getY, targetZ - getZ) + val distance = toTarget.length() + val velocity = getDeltaMovement + if (distance > 0 && (distance > 0.005f || velocity.dot(velocity) > 0.005f)) { val acceleration = math.min(targetAcceleration.floatValue(), distance) / distance val velocityX = velocity.x + toTarget.x * acceleration val velocityY = velocity.y + toTarget.y * acceleration val velocityZ = velocity.z + toTarget.z * acceleration - motionX = math.max(-maxVelocity, math.min(maxVelocity, velocityX)) - motionY = math.max(-maxVelocity, math.min(maxVelocity, velocityY)) - motionZ = math.max(-maxVelocity, math.min(maxVelocity, velocityZ)) + setDeltaMovement(new Vector3d(math.max(-maxVelocity, math.min(maxVelocity, velocityX)), + math.max(-maxVelocity, math.min(maxVelocity, velocityY)), + math.max(-maxVelocity, math.min(maxVelocity, velocityZ)))) } else { - motionX = 0 - motionY = 0 - motionZ = 0 - posX = targetX.floatValue() - posY = targetY.floatValue() - posZ = targetZ.floatValue() + setDeltaMovement(Vector3d.ZERO) + setPos(targetX.floatValue(), targetY.floatValue(), targetZ.floatValue()) } } else { // No power, free fall: engage! - motionY -= gravity + setDeltaMovement(getDeltaMovement.subtract(0, gravity, 0)) } - move(MoverType.SELF, motionX, motionY, motionZ) + move(MoverType.SELF, getDeltaMovement) // Make sure we don't get infinitely faster. if (isRunning) { - motionX *= drag - motionY *= drag - motionZ *= drag + setDeltaMovement(getDeltaMovement.scale(drag)) } else { - val groundDrag = world.getBlock(BlockPosition(this: Entity).offset(EnumFacing.DOWN)).slipperiness * drag - motionX *= groundDrag - motionY *= drag - motionZ *= groundDrag - if (onGround) { - motionY *= -0.5 - } + val groundDrag = world.getBlock(BlockPosition(this: Entity).offset(Direction.DOWN)).getFriction * drag + setDeltaMovement(getDeltaMovement.multiply(groundDrag, drag * (if (isOnGround) -0.5 else 1), groundDrag)) } } - override def hitByEntity(entity: Entity): Boolean = { + override def skipAttackInteraction(entity: Entity): Boolean = { if (isRunning) { - val direction = new Vec3d(entity.posX - posX, entity.posY + entity.getEyeHeight - posY, entity.posZ - posZ).normalize() - if (!world.isRemote) { + val direction = new Vector3d(entity.getX - getX, entity.getY + entity.getEyeHeight - getY, entity.getZ - getZ).normalize() + if (!world.isClientSide) { if (Settings.get.inputUsername) - machine.signal("hit", Double.box(direction.x), Double.box(direction.z), Double.box(direction.y), entity.getName) + machine.signal("hit", Double.box(direction.x), Double.box(direction.z), Double.box(direction.y), entity.getName.getString) else machine.signal("hit", Double.box(direction.x), Double.box(direction.z), Double.box(direction.y)) } - motionX = (motionX - direction.x) * 0.5f - motionY = (motionY - direction.y) * 0.5f - motionZ = (motionZ - direction.z) * 0.5f + setDeltaMovement(getDeltaMovement.subtract(direction).scale(0.5)) } - super.hitByEntity(entity) + super.skipAttackInteraction(entity) + } + + // Not implemented in Drone itself because spectators would open this via vanilla PlayerEntity.openMenu (without extra data). + val containerProvider = new INamedContainerProvider { + override def getDisplayName = StringTextComponent.EMPTY + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Drone(ContainerTypes.DRONE, id, playerInventory, mainInventory, mainInventory.getContainerSize) } - override def processInitialInteract(player: EntityPlayer, hand: EnumHand): Boolean = { - if (isDead) return false - if (player.isSneaking) { - if (Wrench.isWrench(player.getHeldItemMainhand)) { - if(!world.isRemote) { + override def interact(player: PlayerEntity, hand: Hand): ActionResultType = { + if (!isAlive) return ActionResultType.PASS + if (player.isCrouching) { + if (Wrench.isWrench(player.getItemInHand(Hand.MAIN_HAND))) { + if(!world.isClientSide) { outOfWorld() } } - else if (!world.isRemote && !machine.isRunning) { + else if (!world.isClientSide && !machine.isRunning) { start() } } - else if (!world.isRemote) { - player.openGui(OpenComputers, GuiType.Drone.id, world, getEntityId, 0, 0) + else player match { + case srvPlr: ServerPlayerEntity if !world.isClientSide => ContainerTypes.openDroneGui(srvPlr, this) + case _ => } - true + ActionResultType.sidedSuccess(world.isClientSide) } // No step sounds. Except on that one day. - override def playStepSound(pos: BlockPos, block: Block): Unit = { - if (EventHandler.isItTime) super.playStepSound(pos, block) + override def playStepSound(pos: BlockPos, state: BlockState): Unit = { + if (EventHandler.isItTime) super.playStepSound(pos, state) } // ----------------------------------------------------------------------- // private var isChangingDimension = false - override def changeDimension(dimension: Int): Entity = { + override def changeDimension(dimension: ServerWorld): Entity = { // Store relative target as target, to allow adding that in our "new self" // (entities get re-created after changing dimension). - targetX = (targetX - posX).toFloat - targetY = (targetY - posY).toFloat - targetZ = (targetZ - posZ).toFloat + targetX = (targetX - getX).toFloat + targetY = (targetY - getY).toFloat + targetZ = (targetZ - getZ).toFloat try { isChangingDimension = true super.changeDimension(dimension) } finally { isChangingDimension = false - setDead() // Again, to actually close old machine state after copying it. + remove() // Again, to actually close old machine state after copying it. } } - override def copyDataFromOld(entity: Entity): Unit = { - super.copyDataFromOld(entity) + override def restoreFrom(entity: Entity): Unit = { + super.restoreFrom(entity) // Compute relative target based on old position and update, because our // frame of reference most certainly changed (i.e. we'll spawn at different // coordinates than the ones we started traveling from, e.g. when porting // to the nether it'll be oldpos / 8). entity match { case drone: Drone => - targetX = (posX + drone.targetX).toFloat - targetY = (posY + drone.targetY).toFloat - targetZ = (posZ + drone.targetZ).toFloat + targetX = (getX + drone.targetX).toFloat + targetY = (getY + drone.targetY).toFloat + targetZ = (getZ + drone.targetZ).toFloat case _ => - targetX = posX.toFloat - targetY = posY.toFloat - targetZ = posZ.toFloat + targetX = getX.toFloat + targetY = getY.toFloat + targetZ = getZ.toFloat } } - override def setDead() { - super.setDead() - if (!world.isRemote && !isChangingDimension) { + override def remove() { + super.remove() + if (!world.isClientSide && !isChangingDimension) { machine.stop() machine.node.remove() components.disconnectComponents() @@ -556,34 +573,31 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D } override def outOfWorld(): Unit = { - if (isDead) return + if (!isAlive) return super.outOfWorld() - if (!world.isRemote) { + if (!world.isClientSide) { val stack = api.Items.get(Constants.ItemName.Drone).createItemStack(1) info.storedEnergy = control.node.localBuffer.toInt - info.save(stack) - val entity = new EntityItem(world, posX, posY, posZ, stack) - entity.setPickupDelay(15) - world.spawnEntity(entity) + info.saveData(stack) + val entity = new ItemEntity(world, getX, getY, getZ, stack) + entity.setPickUpDelay(15) + world.addFreshEntity(entity) InventoryUtils.dropAllSlots(BlockPosition(this: Entity), mainInventory) } } - override def getName: String = Localization.localizeImmediately("entity.oc.Drone.name") + override def getName: ITextComponent = Localization.localizeLater("entity.oc.Drone.name") - override def handleWaterMovement(): Boolean = { - inWater = world.handleMaterialAcceleration(getEntityBoundingBox, Material.WATER, this) - inWater - } + override protected def getAddEntityPacket = NetworkHooks.getEntitySpawningPacket(this) - override def readEntityFromNBT(nbt: NBTTagCompound) { - info.load(nbt.getCompoundTag("info")) + override protected def readAdditionalSaveData(nbt: CompoundNBT) { + info.loadData(nbt.getCompound("info")) inventorySize = computeInventorySize() - if (!world.isRemote) { - machine.load(nbt.getCompoundTag("machine")) - control.load(nbt.getCompoundTag("control")) - components.load(nbt.getCompoundTag("components")) - mainInventory.load(nbt.getCompoundTag("inventory")) + if (!world.isClientSide) { + machine.loadData(nbt.getCompound("machine")) + control.loadData(nbt.getCompound("control")) + components.loadData(nbt.getCompound("components")) + mainInventory.loadData(nbt.getCompound("inventory")) wireThingsTogether() } @@ -594,35 +608,35 @@ class Drone(world: World) extends Entity(world) with MachineHost with internal.D setSelectedSlot(nbt.getByte("selectedSlot") & 0xFF) setSelectedTank(nbt.getByte("selectedTank") & 0xFF) statusText = nbt.getString("statusText") - lightColor = nbt.getInteger("lightColor") - if (nbt.hasKey("owner")) { + lightColor = nbt.getInt("lightColor") + if (nbt.contains("owner")) { ownerName = nbt.getString("owner") } - if (nbt.hasKey("ownerUuid")) { + if (nbt.contains("ownerUuid")) { ownerUUID = UUID.fromString(nbt.getString("ownerUuid")) } } - override def writeEntityToNBT(nbt: NBTTagCompound) { - if (world.isRemote) return + override protected def addAdditionalSaveData(nbt: CompoundNBT) { + if (world.isClientSide) return components.saveComponents() info.storedEnergy = globalBuffer.toInt - nbt.setNewCompoundTag("info", info.save) - if (!world.isRemote) { - nbt.setNewCompoundTag("machine", machine.save) - nbt.setNewCompoundTag("control", control.save) - nbt.setNewCompoundTag("components", components.save) - nbt.setNewCompoundTag("inventory", mainInventory.save) + nbt.setNewCompoundTag("info", info.saveData) + if (!world.isClientSide) { + nbt.setNewCompoundTag("machine", machine.saveData) + nbt.setNewCompoundTag("control", control.saveData) + nbt.setNewCompoundTag("components", components.saveData) + nbt.setNewCompoundTag("inventory", mainInventory.saveData) } - nbt.setFloat("targetX", targetX) - nbt.setFloat("targetY", targetY) - nbt.setFloat("targetZ", targetZ) - nbt.setFloat("targetAcceleration", targetAcceleration) - nbt.setByte("selectedSlot", selectedSlot.toByte) - nbt.setByte("selectedTank", selectedTank.toByte) - nbt.setString("statusText", statusText) - nbt.setInteger("lightColor", lightColor) - nbt.setString("owner", ownerName) - nbt.setString("ownerUuid", ownerUUID.toString) + nbt.putFloat("targetX", targetX) + nbt.putFloat("targetY", targetY) + nbt.putFloat("targetZ", targetZ) + nbt.putFloat("targetAcceleration", targetAcceleration) + nbt.putByte("selectedSlot", selectedSlot.toByte) + nbt.putByte("selectedTank", selectedTank.toByte) + nbt.putString("statusText", statusText) + nbt.putInt("lightColor", lightColor) + nbt.putString("owner", ownerName) + nbt.putString("ownerUuid", ownerUUID.toString) } } diff --git a/src/main/scala/li/cil/oc/common/entity/EntityTypes.java b/src/main/scala/li/cil/oc/common/entity/EntityTypes.java new file mode 100644 index 0000000000..9e1a61473f --- /dev/null +++ b/src/main/scala/li/cil/oc/common/entity/EntityTypes.java @@ -0,0 +1,31 @@ +package li.cil.oc.common.entity; + +import li.cil.oc.OpenComputers; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.ObjectHolder; + +@ObjectHolder("opencomputers") +public final class EntityTypes { + public static final EntityType DRONE = null; + + @SubscribeEvent + public static void registerEntities(RegistryEvent.Register> e) { + register(e.getRegistry(), "drone", EntityType.Builder.of(Drone::new, EntityClassification.MISC) + .sized(12 / 16f, 6 / 16f).fireImmune()); + } + + private static void register(IForgeRegistry> registry, String name, EntityType.Builder builder) { + EntityType type = builder.build(name); + type.setRegistryName(new ResourceLocation(OpenComputers.ID(), name)); + registry.register(type); + } + + private EntityTypes() { + throw new Error(); + } +} diff --git a/src/main/scala/li/cil/oc/common/event/AngelUpgradeHandler.scala b/src/main/scala/li/cil/oc/common/event/AngelUpgradeHandler.scala index bdb244e210..133d0b6142 100644 --- a/src/main/scala/li/cil/oc/common/event/AngelUpgradeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/AngelUpgradeHandler.scala @@ -3,9 +3,9 @@ package li.cil.oc.common.event import li.cil.oc.api.event.RobotPlaceInAirEvent import li.cil.oc.api.network.Node import li.cil.oc.server.component.UpgradeAngel -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object AngelUpgradeHandler { @SubscribeEvent diff --git a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala index 1e52fe2538..fa9cc65c7c 100644 --- a/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/BlockChangeHandler.scala @@ -2,22 +2,22 @@ package li.cil.oc.common.event import li.cil.oc.common.EventHandler import li.cil.oc.util.BlockPosition -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.entity.Entity -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.util.SoundCategory import net.minecraft.util.SoundEvent import net.minecraft.util.math.BlockPos -import net.minecraft.world.IWorldEventListener import net.minecraft.world.World import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent import scala.collection.mutable /** * @author Vexatos */ +@Deprecated object BlockChangeHandler { def addListener(listener: ChangeListener, coord: BlockPosition) = { @@ -30,44 +30,8 @@ object BlockChangeHandler { private val changeListeners = mutable.WeakHashMap.empty[ChangeListener, BlockPosition] - @SubscribeEvent - def onWorldLoad(e: WorldEvent.Load) { - e.getWorld.addEventListener(new Listener(e.getWorld)) - } - trait ChangeListener { def onBlockChanged() } - private class Listener(world: World) extends IWorldEventListener { - override def notifyBlockUpdate(worldIn: World, pos: BlockPos, oldState: IBlockState, newState: IBlockState, flags: Int): Unit = { - val current = BlockPosition(pos, world) - for ((listener, coord) <- changeListeners) if (coord.equals(current)) { - listener.onBlockChanged() - } - } - - override def spawnParticle(id: Int, ignoreRange: Boolean, p_190570_3_ : Boolean, x: Double, y: Double, z: Double, xSpeed: Double, ySpeed: Double, zSpeed: Double, parameters: Int*): Unit = {} - - override def playRecord(soundIn: SoundEvent, pos: BlockPos): Unit = {} - - override def playEvent(player: EntityPlayer, `type`: Int, blockPosIn: BlockPos, data: Int): Unit = {} - - override def onEntityAdded(entityIn: Entity): Unit = {} - - override def spawnParticle(particleID: Int, ignoreRange: Boolean, xCoord: Double, yCoord: Double, zCoord: Double, xOffset: Double, yOffset: Double, zOffset: Double, parameters: Int*): Unit = {} - - override def onEntityRemoved(entityIn: Entity): Unit = {} - - override def broadcastSound(soundID: Int, pos: BlockPos, data: Int): Unit = {} - - override def playSoundToAllNearExcept(player: EntityPlayer, soundIn: SoundEvent, category: SoundCategory, x: Double, y: Double, z: Double, volume: Float, pitch: Float): Unit = {} - - override def markBlockRangeForRenderUpdate(x1: Int, y1: Int, z1: Int, x2: Int, y2: Int, z2: Int): Unit = {} - - override def sendBlockBreakProgress(breakerId: Int, pos: BlockPos, progress: Int): Unit = {} - - override def notifyLightSet(pos: BlockPos): Unit = {} - } - } diff --git a/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala b/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala index 80395e3bd8..3d81c1b139 100644 --- a/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/ChunkloaderUpgradeHandler.scala @@ -1,6 +1,6 @@ package li.cil.oc.common.event -import java.util +import java.util.UUID import li.cil.oc.OpenComputers import li.cil.oc.api.event.RobotMoveEvent @@ -8,54 +8,87 @@ import li.cil.oc.server.component.UpgradeChunkloader import li.cil.oc.util.BlockPosition import net.minecraft.util.math.ChunkPos import net.minecraft.world.World -import net.minecraftforge.common.ForgeChunkManager -import net.minecraftforge.common.ForgeChunkManager.LoadingCallback -import net.minecraftforge.common.ForgeChunkManager.Ticket +import net.minecraft.world.ForcedChunksSaveData +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.common.world.ForgeChunkManager +import net.minecraftforge.common.world.ForgeChunkManager.LoadingValidationCallback +import net.minecraftforge.common.world.ForgeChunkManager.TicketHelper import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent import net.minecraft.entity.Entity -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ +import scala.collection.immutable import scala.collection.mutable -object ChunkloaderUpgradeHandler extends LoadingCallback { - val restoredTickets = mutable.Map.empty[String, Ticket] +object ChunkloaderUpgradeHandler extends LoadingValidationCallback { + private val restoredTickets = mutable.Map.empty[UUID, ChunkPos] - override def ticketsLoaded(tickets: util.List[Ticket], world: World) { - for (ticket <- tickets) { - val data = ticket.getModData - val address = data.getString("address") - restoredTickets += address -> ticket - if (data.hasKey("x") && data.hasKey("z")) { - val x = data.getInteger("x") - val z = data.getInteger("z") - OpenComputers.log.info(s"Restoring chunk loader ticket for upgrade at chunk ($x, $z) with address $address.") + private def parseAddress(addr: String): Option[UUID] = try { + Some(UUID.fromString(addr)) + } + catch { + case _: RuntimeException => None + } - ForgeChunkManager.forceChunk(ticket, new ChunkPos(x, z)) + def claimTicket(addr: String) = parseAddress(addr).flatMap(restoredTickets.remove) + + override def validateTickets(world: ServerWorld, helper: TicketHelper) { + for ((owner, ticketsPair) <- helper.getEntityTickets) { + // This ensures that malformed tickets are also cleared on world save. + restoredTickets += owner -> null + // Chunkloaders use only ticking tickets. + val tickets = ticketsPair.getSecond + if (tickets.size == 9) { + var (minX, minZ, maxX, maxZ) = (0, 0, 0, 0) + for (combinedPos <- tickets) { + val x = ChunkPos.getX(combinedPos) + val z = ChunkPos.getZ(combinedPos) + minX = minX min x + maxX = maxX max x + minZ = minZ min z + maxZ = maxZ max z + } + if (minX + 2 == maxX && minZ + 2 == maxZ) { + val x = minX + 1 + val z = minZ + 1 + OpenComputers.log.info(s"Restoring chunk loader ticket for upgrade at chunk ($x, $z) with address ${owner}.") + restoredTickets += owner -> new ChunkPos(x, z) + } + else { + OpenComputers.log.warn(s"Chunk loader ticket for $owner loads an incorrect shape.") + helper.removeAllTickets(owner) + } + } + else { + OpenComputers.log.warn(s"Chunk loader ticket for $owner loads ${tickets.size} chunks.") + helper.removeAllTickets(owner) } } } @SubscribeEvent - def onWorldSave(e: WorldEvent.Save) { - // Any tickets that were not reassigned by the time the world gets saved - // again can be considered orphaned, so we release them. - // TODO figure out a better event *after* tile entities were restored - // but *before* the world is saved, because the tickets are saved first, - // so if the save is because the game is being quit the tickets aren't - // actually being cleared. This will *usually* not be a problem, but it - // has room for improvement. - restoredTickets.values.foreach(ticket => { - try{ - val data = ticket.getModData - OpenComputers.log.warn(s"A chunk loader ticket has been orphaned! Address: ${data.getString("address")}, position: (${data.getInteger("x")}, ${data.getInteger("z")}). Removing...") - ForgeChunkManager.releaseTicket(ticket) + def onWorldSave(e: WorldEvent.Save) = e.getWorld match { + case world: ServerWorld => { + // Any tickets that were not reassigned by the time the world gets saved + // again can be considered orphaned, so we release them. + // TODO figure out a better event *after* tile entities were restored + // but *before* the world is saved, because the tickets are saved first, + // so if the save is because the game is being quit the tickets aren't + // actually being cleared. This will *usually* not be a problem, but it + // has room for improvement. + for ((owner, pos) <- restoredTickets) { + try { + OpenComputers.log.warn(s"A chunk loader ticket has been orphaned! Address: ${owner}, position: (${pos.x}, ${pos.z}). Removing...") + releaseTicket(world, owner.toString, pos) + } + catch { + case err: Throwable => OpenComputers.log.error(err) + } } - catch { - case _: Throwable => // Ignored. - } - }) - restoredTickets.clear() + restoredTickets.clear() + } + case _ => } // Note: it might be necessary to use pre move to force load the target chunk @@ -74,23 +107,37 @@ object ChunkloaderUpgradeHandler extends LoadingCallback { }) } - def updateLoadedChunk(loader: UpgradeChunkloader) { - val blockPos = BlockPosition(loader.host) - val centerChunk = new ChunkPos(blockPos.x >> 4, blockPos.z >> 4) - val robotChunks = (for (x <- -1 to 1; z <- -1 to 1) yield new ChunkPos(centerChunk.x + x, centerChunk.z + z)).toSet - - loader.ticket.foreach(ticket => { - ticket.getChunkList.collect { - case chunk: ChunkPos if !robotChunks.contains(chunk) => ForgeChunkManager.unforceChunk(ticket, chunk) + def releaseTicket(world: ServerWorld, addr: String, pos: ChunkPos): Unit = parseAddress(addr) match { + case Some(uuid) => { + for (x <- -1 to 1; z <- -1 to 1) { + ForgeChunkManager.forceChunk(world, OpenComputers.ID, uuid, pos.x + x, pos.z + z, false, true) } + } + case _ => OpenComputers.log.warn("Address '$addr' could not be parsed") + } - for (chunk <- robotChunks) { - ForgeChunkManager.forceChunk(ticket, chunk) + def updateLoadedChunk(loader: UpgradeChunkloader) { + (loader.host.world, parseAddress(loader.node.address)) match { + // If loader.ticket is None that means we shouldn't load anything (as did the old ticketing system). + case (world: ServerWorld, Some(owner)) if loader.ticket.isDefined => { + val blockPos = BlockPosition(loader.host) + val centerChunk = new ChunkPos(blockPos.x >> 4, blockPos.z >> 4) + if (centerChunk != loader.ticket.get) { + val robotChunks = (for (x <- -1 to 1; z <- -1 to 1) yield new ChunkPos(centerChunk.x + x, centerChunk.z + z)).toSet + val existingChunks = loader.ticket match { + case Some(currPos) => (for (x <- -1 to 1; z <- -1 to 1) yield new ChunkPos(currPos.x + x, currPos.z + z)).toSet + case None => immutable.Set.empty[ChunkPos] + } + for (toRemove <- existingChunks if !robotChunks.contains(toRemove)) { + ForgeChunkManager.forceChunk(world, OpenComputers.ID, owner, toRemove.x, toRemove.z, false, true) + } + for (toAdd <- robotChunks if !existingChunks.contains(toAdd)) { + ForgeChunkManager.forceChunk(world, OpenComputers.ID, owner, toAdd.x, toAdd.z, true, true) + } + loader.ticket = Some(centerChunk) + } } - - ticket.getModData.setString("address", loader.node.address) - ticket.getModData.setInteger("x", centerChunk.x) - ticket.getModData.setInteger("z", centerChunk.z) - }) + case _ => + } } } diff --git a/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala b/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala index 7e61d8735a..aa0afbbe1b 100644 --- a/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/ExperienceUpgradeHandler.scala @@ -1,5 +1,6 @@ package li.cil.oc.common.event +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Localization import li.cil.oc.Settings import li.cil.oc.api.event._ @@ -7,10 +8,10 @@ import li.cil.oc.api.internal.Agent import li.cil.oc.api.internal.Robot import li.cil.oc.api.network.Node import li.cil.oc.server.component -import net.minecraft.client.renderer.GlStateManager -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraft.util.Util +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ExperienceUpgradeHandler { @SubscribeEvent @@ -18,7 +19,7 @@ object ExperienceUpgradeHandler { val (level, experience) = getLevelAndExperience(e.agent) // This is basically a 'does it have an experience upgrade' check. if (experience != 0.0) { - e.player.sendMessage(Localization.Analyzer.RobotXp(experience, level)) + e.player.sendMessage(Localization.Analyzer.RobotXp(experience, level), Util.NIL_UUID) } } @@ -37,7 +38,7 @@ object ExperienceUpgradeHandler { def onRobotAttackEntityPost(e: RobotAttackEntityEvent.Post) { e.agent match { case robot: Robot => - if (robot.equipmentInventory.getStackInSlot(0) != null && e.target.isDead) { + if (robot.equipmentInventory.getItem(0) != null && !e.target.isAlive) { addExperience(robot, Settings.get.robotActionXp) } case _ => @@ -69,7 +70,7 @@ object ExperienceUpgradeHandler { val level = e.agent match { case robot: Robot => var acc = 0 - for (index <- 0 until robot.getSizeInventory) { + for (index <- 0 until robot.getContainerSize) { robot.getComponentInSlot(index) match { case upgrade: component.UpgradeExperience => acc += upgrade.level @@ -80,13 +81,10 @@ object ExperienceUpgradeHandler { case _ => 0 } if (level > 19) { - GlStateManager.color(0.4f, 1, 1) + e.multiplyColors(0.4f, 1, 1) } else if (level > 9) { - GlStateManager.color(1, 1, 0.4f) - } - else { - GlStateManager.color(0.5f, 0.5f, 0.5f) + e.multiplyColors(1, 1, 0.4f) } } diff --git a/src/main/scala/li/cil/oc/common/event/FileSystemAccessHandler.scala b/src/main/scala/li/cil/oc/common/event/FileSystemAccessHandler.scala index a4f2ddb37a..1c9dbcacde 100644 --- a/src/main/scala/li/cil/oc/common/event/FileSystemAccessHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/FileSystemAccessHandler.scala @@ -11,14 +11,14 @@ import li.cil.oc.server.component.Server import net.minecraft.util.ResourceLocation import net.minecraft.util.SoundCategory import net.minecraft.util.SoundEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent object FileSystemAccessHandler { @SubscribeEvent def onFileSystemAccess(e: FileSystemAccessEvent.Server) { - e.getTileEntity match { + e.getBlockEntity match { case t: Rack => - for (slot <- 0 until t.getSizeInventory) { + for (slot <- 0 until t.getContainerSize) { t.getMountable(slot) match { case server: Server => val containsNode = server.componentSlot(e.getNode.address) >= 0 @@ -43,8 +43,8 @@ object FileSystemAccessHandler { def onFileSystemAccess(e: FileSystemAccessEvent.Client) { val volume = Settings.get.soundVolume val sound = new SoundEvent(new ResourceLocation(e.getSound)) - e.getWorld.playSound(e.getX, e.getY, e.getZ, sound, SoundCategory.BLOCKS, volume, 1, false) - e.getTileEntity match { + e.getWorld.playLocalSound(e.getX, e.getY, e.getZ, sound, SoundCategory.BLOCKS, volume, 1, false) + e.getBlockEntity match { case t: DiskDrive => t.lastAccess = System.currentTimeMillis() case t: Case => t.lastFileSystemAccess = System.currentTimeMillis() case t: Raid => t.lastAccess = System.currentTimeMillis() diff --git a/src/main/scala/li/cil/oc/common/event/HoverBootsHandler.scala b/src/main/scala/li/cil/oc/common/event/HoverBootsHandler.scala index d990c8f341..8d621f5e9a 100644 --- a/src/main/scala/li/cil/oc/common/event/HoverBootsHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/HoverBootsHandler.scala @@ -1,27 +1,28 @@ package li.cil.oc.common.event +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.Settings import li.cil.oc.common.item.HoverBoots -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent import net.minecraftforge.event.entity.living.LivingFallEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object HoverBootsHandler { @SubscribeEvent def onLivingUpdate(e: LivingUpdateEvent): Unit = e.getEntity match { - case player: EntityPlayer if !player.isInstanceOf[FakePlayer] => - val nbt = player.getEntityData + case player: PlayerEntity if !player.isInstanceOf[FakePlayer] => + val nbt = player.getPersistentData val hadHoverBoots = nbt.getBoolean(Settings.namespace + "hasHoverBoots") - val hasHoverBoots = !player.isSneaking && equippedArmor(player).exists(stack => stack.getItem match { + val hasHoverBoots = !player.isCrouching && equippedArmor(player).exists(stack => stack.getItem match { case boots: HoverBoots => Settings.get.ignorePower || { - if (player.onGround && !player.capabilities.isCreativeMode && player.world.getTotalWorldTime % Settings.get.tickFrequency == 0) { - val velocity = player.motionX * player.motionX + player.motionY * player.motionY + player.motionZ * player.motionZ + if (player.isOnGround && !player.isCreative && player.level.getGameTime % Settings.get.tickFrequency == 0) { + val velocity = player.getDeltaMovement.lengthSqr if (velocity > 0.015f) { boots.charge(stack, -Settings.get.hoverBootMove, simulate = false) } @@ -31,29 +32,30 @@ object HoverBootsHandler { case _ => false }) if (hasHoverBoots != hadHoverBoots) { - nbt.setBoolean(Settings.namespace + "hasHoverBoots", hasHoverBoots) - player.stepHeight = if (hasHoverBoots) 1f else 0.5f + nbt.putBoolean(Settings.namespace + "hasHoverBoots", hasHoverBoots) + player.maxUpStep = if (hasHoverBoots) 1f else 0.5f } - if (hasHoverBoots && !player.onGround && player.fallDistance < 5 && player.motionY < 0) { - player.motionY *= 0.9f + if (hasHoverBoots && !player.isOnGround && player.fallDistance < 5 && player.getDeltaMovement.y < 0) { + player.setDeltaMovement(player.getDeltaMovement.multiply(1, 0.9, 1)) } case _ => // Ignore. } @SubscribeEvent def onLivingJump(e: LivingJumpEvent): Unit = e.getEntity match { - case player: EntityPlayer if !player.isInstanceOf[FakePlayer] && !player.isSneaking => + case player: PlayerEntity if !player.isInstanceOf[FakePlayer] && !player.isCrouching => equippedArmor(player).collectFirst { case stack if stack.getItem.isInstanceOf[HoverBoots] => val boots = stack.getItem.asInstanceOf[HoverBoots] val hoverJumpCost = -Settings.get.hoverBootJump - val isCreative = Settings.get.ignorePower || player.capabilities.isCreativeMode + val isCreative = Settings.get.ignorePower || player.isCreative if (isCreative || boots.charge(stack, hoverJumpCost, simulate = true) == 0) { if (!isCreative) boots.charge(stack, hoverJumpCost, simulate = false) + val motion = player.getDeltaMovement if (player.isSprinting) - player.addVelocity(player.motionX * 0.5, 0.4, player.motionZ * 0.5) + player.push(motion.x * 0.5, 0.4, motion.z * 0.5) else - player.addVelocity(0, 0.4, 0) + player.push(0, 0.4, 0) } } case _ => // Ignore. @@ -61,12 +63,12 @@ object HoverBootsHandler { @SubscribeEvent def onLivingFall(e: LivingFallEvent): Unit = if (e.getDistance > 3) e.getEntity match { - case player: EntityPlayer if !player.isInstanceOf[FakePlayer] => + case player: PlayerEntity if !player.isInstanceOf[FakePlayer] => equippedArmor(player).collectFirst { case stack if stack.getItem.isInstanceOf[HoverBoots] => val boots = stack.getItem.asInstanceOf[HoverBoots] val hoverFallCost = -Settings.get.hoverBootAbsorb - val isCreative = Settings.get.ignorePower || player.capabilities.isCreativeMode + val isCreative = Settings.get.ignorePower || player.isCreative if (isCreative || boots.charge(stack, hoverFallCost, simulate = true) == 0) { if (!isCreative) boots.charge(stack, hoverFallCost, simulate = false) e.setDistance(e.getDistance * 0.3f) @@ -75,5 +77,5 @@ object HoverBootsHandler { case _ => // Ignore. } - private def equippedArmor(player: EntityPlayer) = player.getArmorInventoryList.filter(!_.isEmpty) + private def equippedArmor(player: PlayerEntity) = player.inventory.armor.filter(!_.isEmpty) } diff --git a/src/main/scala/li/cil/oc/common/event/NanomachinesHandler.scala b/src/main/scala/li/cil/oc/common/event/NanomachinesHandler.scala index 05238940cf..fa272c7750 100644 --- a/src/main/scala/li/cil/oc/common/event/NanomachinesHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/NanomachinesHandler.scala @@ -3,42 +3,48 @@ package li.cil.oc.common.event import java.io.FileInputStream import java.io.FileOutputStream +import com.mojang.blaze3d.matrix.MatrixStack +import com.mojang.blaze3d.vertex.IVertexBuilder import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.nanomachines.Controller import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.common.EventHandler import li.cil.oc.common.nanomachines.ControllerImpl import net.minecraft.client.Minecraft -import net.minecraft.client.gui.ScaledResolution +import net.minecraft.client.renderer.IRenderTypeBuffer import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.vertex.DefaultVertexFormats -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraftforge.client.event.RenderGameOverlayEvent import net.minecraftforge.event.entity.living.LivingEvent import net.minecraftforge.event.entity.player.PlayerEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent -import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent -import org.lwjgl.opengl.GL11 +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent +import net.minecraftforge.event.entity.player.PlayerEvent.PlayerRespawnEvent object NanomachinesHandler { object Client { + val TexNanomachines = RenderTypes.createTexturedQuad("nanomachines", Textures.GUI.Nanomachines, DefaultVertexFormats.POSITION_TEX, false) + val TexNanomachinesBar = RenderTypes.createTexturedQuad("nanomachines_bar", Textures.GUI.NanomachinesBar, DefaultVertexFormats.POSITION_TEX, false) + @SubscribeEvent def onRenderGameOverlay(e: RenderGameOverlayEvent.Post): Unit = { if (e.getType == RenderGameOverlayEvent.ElementType.TEXT) { - val mc = Minecraft.getMinecraft + val mc = Minecraft.getInstance api.Nanomachines.getController(mc.player) match { case controller: Controller => - val res = new ScaledResolution(mc) + val stack = e.getMatrixStack + val window = mc.getWindow val sizeX = 8 val sizeY = 12 - val width = res.getScaledWidth - val height = res.getScaledHeight + val width = window.getGuiScaledWidth + val height = window.getGuiScaledHeight val (x, y) = Settings.get.nanomachineHudPos val left = math.min(width - sizeX, @@ -51,33 +57,29 @@ object NanomachinesHandler { else if (y < 1) y * height else y) val fill = controller.getLocalBuffer / controller.getLocalBufferSize - Minecraft.getMinecraft.getTextureManager.bindTexture(Textures.GUI.Nanomachines) - drawRect(left.toInt, top.toInt, sizeX, sizeY, sizeX, sizeY) - Minecraft.getMinecraft.getTextureManager.bindTexture(Textures.GUI.NanomachinesBar) - drawRect(left.toInt, top.toInt, sizeX, sizeY, sizeX, sizeY, fill) + val buffer = IRenderTypeBuffer.immediate(Tessellator.getInstance.getBuilder) + drawRect(stack, buffer.getBuffer(TexNanomachines), left.toInt, top.toInt, sizeX, sizeY, sizeX, sizeY) + drawRect(stack, buffer.getBuffer(TexNanomachinesBar), left.toInt, top.toInt, sizeX, sizeY, sizeX, sizeY, fill.toFloat) + buffer.endBatch() case _ => // Nothing to show. } } } - private def drawRect(x: Int, y: Int, w: Int, h: Int, tw: Int, th: Int, fill: Double = 1) { + private def drawRect(stack: MatrixStack, r: IVertexBuilder, x: Int, y: Int, w: Int, h: Int, tw: Int, th: Int, fill: Float = 1) { val sx = 1f / tw val sy = 1f / th - val t = Tessellator.getInstance - val r = t.getBuffer - r.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX) - r.pos(x, y + h, 0).tex(0, h * sy).endVertex() - r.pos(x + w, y + h, 0).tex(w * sx, h * sy).endVertex() - r.pos(x + w, y + h * (1 - fill), 0).tex(w * sx, 1 - fill).endVertex() - r.pos(x, y + h * (1 - fill), 0).tex(0, 1 - fill).endVertex() - t.draw() + r.vertex(stack.last.pose, x, y + h, 0).uv(0, h * sy).endVertex() + r.vertex(stack.last.pose, x + w, y + h, 0).uv(w * sx, h * sy).endVertex() + r.vertex(stack.last.pose, x + w, y + h * (1 - fill), 0).uv(w * sx, 1 - fill).endVertex() + r.vertex(stack.last.pose, x, y + h * (1 - fill), 0).uv(0, 1 - fill).endVertex() } } object Common { @SubscribeEvent def onPlayerRespawn(e: PlayerRespawnEvent): Unit = { - api.Nanomachines.getController(e.player) match { + api.Nanomachines.getController(e.getPlayer) match { case controller: Controller => controller.changeBuffer(-controller.getLocalBuffer) case _ => // Not a player with nanomachines. } @@ -86,19 +88,19 @@ object NanomachinesHandler { @SubscribeEvent def onLivingUpdate(e: LivingEvent.LivingUpdateEvent): Unit = { e.getEntity match { - case player: EntityPlayer => api.Nanomachines.getController(player) match { + case player: PlayerEntity => api.Nanomachines.getController(player) match { case controller: ControllerImpl => if (controller.player eq player) { controller.update() } else { // Player entity instance changed (e.g. respawn), recreate the controller. - val nbt = new NBTTagCompound() - controller.save(nbt) + val nbt = new CompoundNBT() + controller.saveData(nbt) api.Nanomachines.uninstallController(controller.player) api.Nanomachines.installController(player) match { case newController: ControllerImpl => - newController.load(nbt) + newController.loadData(nbt) newController.reset() case _ => // Eh? } @@ -112,11 +114,11 @@ object NanomachinesHandler { @SubscribeEvent def onPlayerSave(e: PlayerEvent.SaveToFile): Unit = { val file = e.getPlayerFile("ocnm") - api.Nanomachines.getController(e.getEntityPlayer) match { + api.Nanomachines.getController(e.getPlayer) match { case controller: ControllerImpl => try { - val nbt = new NBTTagCompound() - controller.save(nbt) + val nbt = new CompoundNBT() + controller.saveData(nbt) val fos = new FileOutputStream(file) try CompressedStreamTools.writeCompressed(nbt, fos) catch { case t: Throwable => @@ -136,11 +138,11 @@ object NanomachinesHandler { def onPlayerLoad(e: PlayerEvent.LoadFromFile): Unit = { val file = e.getPlayerFile("ocnm") if (file.exists()) { - api.Nanomachines.getController(e.getEntityPlayer) match { + api.Nanomachines.getController(e.getPlayer) match { case controller: ControllerImpl => try { val fis = new FileInputStream(file) - try controller.load(CompressedStreamTools.readCompressed(fis)) catch { + try controller.loadData(CompressedStreamTools.readCompressed(fis)) catch { case t: Throwable => OpenComputers.log.warn("Error loading nanomachine state.", t) } @@ -157,10 +159,10 @@ object NanomachinesHandler { @SubscribeEvent def onPlayerDisconnect(e: PlayerLoggedOutEvent): Unit = { - api.Nanomachines.getController(e.player) match { + api.Nanomachines.getController(e.getPlayer) match { case controller: ControllerImpl => // Wait a tick because saving is done after this event. - EventHandler.scheduleServer(() => api.Nanomachines.uninstallController(e.player)) + EventHandler.scheduleServer(() => api.Nanomachines.uninstallController(e.getPlayer)) case _ => // Not a player with nanomachines. } } diff --git a/src/main/scala/li/cil/oc/common/event/NetworkActivityHandler.scala b/src/main/scala/li/cil/oc/common/event/NetworkActivityHandler.scala index 934b851ce8..6a10705bf1 100644 --- a/src/main/scala/li/cil/oc/common/event/NetworkActivityHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/NetworkActivityHandler.scala @@ -4,14 +4,14 @@ import li.cil.oc.api.event.NetworkActivityEvent import li.cil.oc.api.internal.Rack import li.cil.oc.common.tileentity.Case import li.cil.oc.server.component.Server -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent object NetworkActivityHandler { @SubscribeEvent def onNetworkActivity(e: NetworkActivityEvent.Server) { - e.getTileEntity match { + e.getBlockEntity match { case t: Rack => - for (slot <- 0 until t.getSizeInventory) { + for (slot <- 0 until t.getContainerSize) { t.getMountable(slot) match { case server: Server => val containsNode = server.componentSlot(e.getNode.address) >= 0 @@ -28,7 +28,7 @@ object NetworkActivityHandler { @SubscribeEvent def onNetworkActivity(e: NetworkActivityEvent.Client) { - e.getTileEntity match { + e.getBlockEntity match { case t: Case => t.lastNetworkActivity = System.currentTimeMillis(); case _ => } diff --git a/src/main/scala/li/cil/oc/common/event/RackMountableRenderHandler.scala b/src/main/scala/li/cil/oc/common/event/RackMountableRenderHandler.scala index 033172a3b4..057a839684 100644 --- a/src/main/scala/li/cil/oc/common/event/RackMountableRenderHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/RackMountableRenderHandler.scala @@ -1,22 +1,25 @@ package li.cil.oc.common.event +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.Constants import li.cil.oc.api import li.cil.oc.api.event.RackMountableRenderEvent import li.cil.oc.client.Textures +import li.cil.oc.client.renderer.RenderTypes import li.cil.oc.client.renderer.tileentity.RenderUtil import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.OpenGlHelper -import net.minecraft.client.renderer.block.model.ItemCameraTransforms -import net.minecraft.entity.item.EntityItem +import net.minecraft.client.renderer.model.ItemCameraTransforms +import net.minecraft.entity.item.ItemEntity import net.minecraft.item.ItemStack +import net.minecraft.util.ResourceLocation +import net.minecraft.util.math.vector.Vector3f import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent import org.lwjgl.opengl.GL11 +import org.lwjgl.opengl.GL13 object RackMountableRenderHandler { lazy val DiskDriveMountable = api.Items.get(Constants.ItemName.DiskDriveMountable) @@ -32,90 +35,77 @@ object RackMountableRenderHandler { @SubscribeEvent def onRackMountableRendering(e: RackMountableRenderEvent.TileEntity): Unit = { - if (e.data != null && DiskDriveMountable == api.Items.get(e.rack.getStackInSlot(e.mountable))) { + if (e.data != null && DiskDriveMountable == api.Items.get(e.rack.getItem(e.mountable))) { // Disk drive. - if (e.data.hasKey("disk")) { - val stack = new ItemStack(e.data.getCompoundTag("disk")) + if (e.data.contains("disk")) { + val stack = ItemStack.of(e.data.getCompound("disk")) if (!stack.isEmpty) { - GlStateManager.pushMatrix() - GlStateManager.scale(1, -1, 1) - GlStateManager.translate(10 / 16f, -(3.5f + e.mountable * 3f) / 16f, -2 / 16f) - GlStateManager.rotate(90, -1, 0, 0) - GlStateManager.scale(0.5f, 0.5f, 0.5f) - - val brightness = e.rack.world.getLightBrightnessForSkyBlocks(BlockPosition(e.rack).offset(e.rack.facing), 0) - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, brightness % 65536, brightness / 65536) - - // This is very 'meh', but item frames do it like this, too! - val entity = new EntityItem(e.rack.world, 0, 0, 0, stack) - entity.hoverStart = 0 - Minecraft.getMinecraft.getRenderItem.renderItem(entity.getItem, ItemCameraTransforms.TransformType.FIXED) - GlStateManager.popMatrix() + val matrix = e.stack + matrix.pushPose() + matrix.scale(1, -1, 1) + matrix.translate(10 / 16f, -(3.5f + e.mountable * 3f) / 16f, -2 / 16f) + matrix.mulPose(Vector3f.XN.rotationDegrees(90)) + matrix.scale(0.5f, 0.5f, 0.5f) + + Minecraft.getInstance.getItemRenderer.renderStatic(stack, ItemCameraTransforms.TransformType.FIXED, e.light, e.overlay, matrix, e.typeBuffer) + matrix.popPose() } } - if (System.currentTimeMillis() - e.data.getLong("lastAccess") < 400 && e.rack.world.rand.nextDouble() > 0.1) { - RenderState.disableEntityLighting() - RenderState.makeItBlend() - - e.renderOverlayFromAtlas(Textures.Block.RackDiskDriveActivity) - - RenderState.disableBlend() - RenderState.enableEntityLighting() + if (System.currentTimeMillis() - e.data.getLong("lastAccess") < 400 && e.rack.world.random.nextDouble() > 0.1) { + renderOverlayFromAtlas(e, Textures.Block.RackDiskDriveActivity) } } - else if (e.data != null && Servers.contains(api.Items.get(e.rack.getStackInSlot(e.mountable)))) { + else if (e.data != null && Servers.contains(api.Items.get(e.rack.getItem(e.mountable)))) { // Server. - RenderState.disableEntityLighting() - RenderState.makeItBlend() - if (e.data.getBoolean("isRunning")) { - e.renderOverlayFromAtlas(Textures.Block.RackServerOn) + renderOverlayFromAtlas(e, Textures.Block.RackServerOn) } if (e.data.getBoolean("hasErrored") && RenderUtil.shouldShowErrorLight(e.rack.hashCode * (e.mountable + 1))) { - e.renderOverlayFromAtlas(Textures.Block.RackServerError) + renderOverlayFromAtlas(e, Textures.Block.RackServerError) } - if (System.currentTimeMillis() - e.data.getLong("lastFileSystemAccess") < 400 && e.rack.world.rand.nextDouble() > 0.1) { - e.renderOverlayFromAtlas(Textures.Block.RackServerActivity) + if (System.currentTimeMillis() - e.data.getLong("lastFileSystemAccess") < 400 && e.rack.world.random.nextDouble() > 0.1) { + renderOverlayFromAtlas(e, Textures.Block.RackServerActivity) } if ((System.currentTimeMillis() - e.data.getLong("lastNetworkActivity") < 300 && System.currentTimeMillis() % 200 > 100) && e.data.getBoolean("isRunning")) { - e.renderOverlayFromAtlas(Textures.Block.RackServerNetworkActivity) + renderOverlayFromAtlas(e, Textures.Block.RackServerNetworkActivity) } - - RenderState.disableBlend() - RenderState.enableEntityLighting() } - else if (e.data != null && TerminalServer == api.Items.get(e.rack.getStackInSlot(e.mountable))) { + else if (e.data != null && TerminalServer == api.Items.get(e.rack.getItem(e.mountable))) { // Terminal server. - RenderState.disableEntityLighting() - RenderState.makeItBlend() - - e.renderOverlayFromAtlas(Textures.Block.RackTerminalServerOn) - val countConnected = e.data.getTagList("keys", NBT.TAG_STRING).tagCount() + renderOverlayFromAtlas(e, Textures.Block.RackTerminalServerOn) + val countConnected = e.data.getList("keys", NBT.TAG_STRING).size() if (countConnected > 0) { val u0 = 7 / 16f val u1 = u0 + (2 * countConnected - 1) / 16f - e.renderOverlayFromAtlas(Textures.Block.RackTerminalServerPresence, u0, u1) + renderOverlayFromAtlas(e, Textures.Block.RackTerminalServerPresence, u0, u1) } - - RenderState.disableBlend() - RenderState.enableEntityLighting() } } + private def renderOverlayFromAtlas(e: RackMountableRenderEvent.TileEntity, texture: ResourceLocation, u0: Float = 0, u1: Float = 1) { + val matrix = e.stack.last.pose + val r = e.typeBuffer.getBuffer(RenderTypes.BLOCK_OVERLAY) + val icon = Textures.getSprite(texture) + r.vertex(matrix, u0, e.v1, 0).uv(icon.getU(u0 * 16), icon.getV(e.v1 * 16)).endVertex(); + r.vertex(matrix, u1, e.v1, 0).uv(icon.getU(u1 * 16), icon.getV(e.v1 * 16)).endVertex(); + r.vertex(matrix, u1, e.v0, 0).uv(icon.getU(u1 * 16), icon.getV(e.v0 * 16)).endVertex(); + r.vertex(matrix, u0, e.v0, 0).uv(icon.getU(u0 * 16), icon.getV(e.v0 * 16)).endVertex(); + } + @SubscribeEvent def onRackMountableRendering(e: RackMountableRenderEvent.Block): Unit = { - if (DiskDriveMountable == api.Items.get(e.rack.getStackInSlot(e.mountable))) { + if (DiskDriveMountable == api.Items.get(e.rack.getItem(e.mountable))) { // Disk drive. e.setFrontTextureOverride(Textures.getSprite(Textures.Block.RackDiskDrive)) } - else if (Servers.contains(api.Items.get(e.rack.getStackInSlot(e.mountable)))) { + else if (Servers.contains(api.Items.get(e.rack.getItem(e.mountable)))) { // Server. e.setFrontTextureOverride(Textures.getSprite(Textures.Block.RackServer)) } - else if (TerminalServer == api.Items.get(e.rack.getStackInSlot(e.mountable))) { + else if (TerminalServer == api.Items.get(e.rack.getItem(e.mountable))) { // Terminal server. e.setFrontTextureOverride(Textures.getSprite(Textures.Block.RackTerminalServer)) } diff --git a/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala b/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala index ed0485591e..603843da0e 100644 --- a/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/RobotCommonHandler.scala @@ -5,24 +5,23 @@ import li.cil.oc.api.event.RobotMoveEvent import li.cil.oc.api.event.RobotUsedToolEvent import li.cil.oc.api.internal import li.cil.oc.api.internal.Robot -import li.cil.oc.common.item.Delegator import li.cil.oc.common.item.UpgradeHover import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraft.util.Direction +import net.minecraftforge.eventbus.api.SubscribeEvent object RobotCommonHandler { @SubscribeEvent def onRobotApplyDamageRate(e: RobotUsedToolEvent.ApplyDamageRate) { e.agent match { case robot: internal.Robot => - if (e.toolAfterUse.isItemStackDamageable) { - val damage = e.toolAfterUse.getItemDamage - e.toolBeforeUse.getItemDamage + if (e.toolAfterUse.isDamageableItem) { + val damage = e.toolAfterUse.getDamageValue - e.toolBeforeUse.getDamageValue if (damage > 0) { val actualDamage = damage * e.getDamageRate - val repairedDamage = if (e.agent.player.getRNG.nextDouble() > 0.5) damage - math.floor(actualDamage).toInt else damage - math.ceil(actualDamage).toInt - e.toolAfterUse.setItemDamage(e.toolAfterUse.getItemDamage - repairedDamage) + val repairedDamage = if (e.agent.player.getRandom.nextDouble() > 0.5) damage - math.floor(actualDamage).toInt else damage - math.ceil(actualDamage).toInt + e.toolAfterUse.setDamageValue(e.toolAfterUse.getDamageValue - repairedDamage) } } case _ => @@ -36,20 +35,21 @@ object RobotCommonHandler { val world = robot.world var maxFlyingHeight = Settings.get.limitFlightHeight - (0 until robot.equipmentInventory.getSizeInventory). - map(robot.equipmentInventory.getStackInSlot). - map(Delegator.subItem). - collect { case Some(item: UpgradeHover) => maxFlyingHeight = math.max(maxFlyingHeight, Settings.get.upgradeFlightHeight(item.tier)) } + (0 until robot.equipmentInventory.getContainerSize). + map(robot.equipmentInventory.getItem(_).getItem). + collect { case item: UpgradeHover => maxFlyingHeight = math.max(maxFlyingHeight, Settings.get.upgradeFlightHeight(item.tier)) } (0 until robot.componentCount). - map(_ + robot.mainInventory.getSizeInventory + robot.equipmentInventory.getSizeInventory). - map(robot.getStackInSlot). - map(Delegator.subItem). - collect { case Some(item: UpgradeHover) => maxFlyingHeight = math.max(maxFlyingHeight, Settings.get.upgradeFlightHeight(item.tier)) } + map(_ + robot.mainInventory.getContainerSize + robot.equipmentInventory.getContainerSize). + map(robot.getItem(_).getItem). + collect { case item: UpgradeHover => maxFlyingHeight = math.max(maxFlyingHeight, Settings.get.upgradeFlightHeight(item.tier)) } - def isMovingDown = e.direction == EnumFacing.DOWN - def hasAdjacentBlock(pos: BlockPosition) = EnumFacing.values.exists(side => world.isSideSolid(pos.offset(side), side.getOpposite)) - def isWithinFlyingHeight(pos: BlockPosition) = maxFlyingHeight >= world.getHeight || (1 to maxFlyingHeight).exists(n => !world.isAirBlock(pos.offset(EnumFacing.DOWN, n))) + def isMovingDown = e.direction == Direction.DOWN + def hasAdjacentBlock(pos: BlockPosition) = Direction.values.exists(side => { + val sidePos = pos.offset(side).toBlockPos + world.getBlockState(sidePos).isFaceSturdy(world, sidePos, side.getOpposite) + }) + def isWithinFlyingHeight(pos: BlockPosition) = maxFlyingHeight >= world.getHeight() || (1 to maxFlyingHeight).exists(n => !world.isAirBlock(pos.offset(Direction.DOWN, n))) val startPos = BlockPosition(robot) val targetPos = startPos.offset(e.direction) // New movement rules as of 1.5: diff --git a/src/main/scala/li/cil/oc/common/event/WirelessNetworkCardHandler.scala b/src/main/scala/li/cil/oc/common/event/WirelessNetworkCardHandler.scala index 1075e28949..a5bc98579e 100644 --- a/src/main/scala/li/cil/oc/common/event/WirelessNetworkCardHandler.scala +++ b/src/main/scala/li/cil/oc/common/event/WirelessNetworkCardHandler.scala @@ -3,9 +3,9 @@ package li.cil.oc.common.event import li.cil.oc.api import li.cil.oc.api.event.RobotMoveEvent import li.cil.oc.server.component.WirelessNetworkCard -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object WirelessNetworkCardHandler { @SubscribeEvent diff --git a/src/main/scala/li/cil/oc/common/init/Blocks.scala b/src/main/scala/li/cil/oc/common/init/Blocks.scala index c37b790b08..c2d0066322 100644 --- a/src/main/scala/li/cil/oc/common/init/Blocks.scala +++ b/src/main/scala/li/cil/oc/common/init/Blocks.scala @@ -1,92 +1,64 @@ package li.cil.oc.common.init import li.cil.oc.Constants +import li.cil.oc.CreativeTab import li.cil.oc.Settings import li.cil.oc.common.Tier import li.cil.oc.common.block._ -import li.cil.oc.common.recipe.Recipes -import li.cil.oc.common.tileentity -import net.minecraft.tileentity.TileEntity -import net.minecraftforge.fml.common.registry.GameRegistry +import net.minecraft.block.AbstractBlock.Properties +import net.minecraft.block.material.Material +import net.minecraft.item.Rarity +import net.minecraft.item.Item object Blocks { def init() { - registerTileEntity(classOf[tileentity.Adapter], Settings.namespace + "adapter") - registerTileEntity(classOf[tileentity.Assembler], Settings.namespace + "assembler") - registerTileEntity(classOf[tileentity.Cable], Settings.namespace + "cable") - registerTileEntity(classOf[tileentity.Capacitor], Settings.namespace + "capacitor") - registerTileEntity(classOf[tileentity.CarpetedCapacitor], Settings.namespace + "carpetedCapacitor") - registerTileEntity(classOf[tileentity.Case], Settings.namespace + "case") - registerTileEntity(classOf[tileentity.Charger], Settings.namespace + "charger") - registerTileEntity(classOf[tileentity.DiskDrive], Settings.namespace + "diskDrive") - registerTileEntity(classOf[tileentity.Disassembler], Settings.namespace + "disassembler") - registerTileEntity(classOf[tileentity.Keyboard], Settings.namespace + "keyboard") - registerTileEntity(classOf[tileentity.Hologram], Settings.namespace + "hologram") - registerTileEntity(classOf[tileentity.Geolyzer], Settings.namespace + "geolyzer") - registerTileEntity(classOf[tileentity.Microcontroller], Settings.namespace + "microcontroller") - registerTileEntity(classOf[tileentity.MotionSensor], Settings.namespace + "motionSensor") - registerTileEntity(classOf[tileentity.NetSplitter], Settings.namespace + "netSplitter") - registerTileEntity(classOf[tileentity.PowerConverter], Settings.namespace + "powerConverter") - registerTileEntity(classOf[tileentity.PowerDistributor], Settings.namespace + "powerDistributor") - registerTileEntity(classOf[tileentity.Print], Settings.namespace + "print") - registerTileEntity(classOf[tileentity.Printer], Settings.namespace + "printer") - registerTileEntity(classOf[tileentity.Raid], Settings.namespace + "raid") - registerTileEntity(classOf[tileentity.Redstone], Settings.namespace + "redstone") - registerTileEntity(classOf[tileentity.Relay], Settings.namespace + "relay") - registerTileEntity(classOf[tileentity.RobotProxy], Settings.namespace + "robot") - registerTileEntity(classOf[tileentity.Screen], Settings.namespace + "screen") - registerTileEntity(classOf[tileentity.Rack], Settings.namespace + "rack") - registerTileEntity(classOf[tileentity.Transposer], Settings.namespace + "transposer") - registerTileEntity(classOf[tileentity.Waypoint], Settings.namespace + "waypoint") + def defaultProps = Properties.of(Material.METAL).strength(2, 5) + def defaultItemProps = new Item.Properties().tab(CreativeTab) + Items.registerBlock(new Adapter(defaultProps), Constants.BlockName.Adapter, defaultItemProps) + Items.registerBlock(new Assembler(defaultProps), Constants.BlockName.Assembler, defaultItemProps) + Items.registerBlock(new Cable(defaultProps), Constants.BlockName.Cable, defaultItemProps) + Items.registerBlock(new Capacitor(defaultProps), Constants.BlockName.Capacitor, defaultItemProps) + Items.registerBlock(new Case(defaultProps, Tier.One), Constants.BlockName.CaseTier1, defaultItemProps) + Items.registerBlock(new Case(defaultProps, Tier.Three), Constants.BlockName.CaseTier3, defaultItemProps.rarity(Rarity.RARE)) + Items.registerBlock(new Case(defaultProps, Tier.Two), Constants.BlockName.CaseTier2, defaultItemProps.rarity(Rarity.UNCOMMON)) + Items.registerBlock(new ChameliumBlock(Properties.of(Material.STONE).strength(2, 5)), Constants.BlockName.ChameliumBlock, defaultItemProps) + Items.registerBlock(new Charger(defaultProps), Constants.BlockName.Charger, defaultItemProps) + Items.registerBlock(new Disassembler(defaultProps), Constants.BlockName.Disassembler, defaultItemProps) + Items.registerBlock(new DiskDrive(defaultProps), Constants.BlockName.DiskDrive, defaultItemProps) + Items.registerBlock(new Geolyzer(defaultProps), Constants.BlockName.Geolyzer, defaultItemProps) + Items.registerBlock(new Hologram(defaultProps, Tier.One), Constants.BlockName.HologramTier1, defaultItemProps) + Items.registerBlock(new Hologram(defaultProps, Tier.Two), Constants.BlockName.HologramTier2, defaultItemProps.rarity(Rarity.UNCOMMON)) + Items.registerBlock(new Keyboard(Properties.of(Material.STONE).strength(2, 5).noOcclusion), Constants.BlockName.Keyboard, defaultItemProps) + Items.registerBlock(new MotionSensor(defaultProps), Constants.BlockName.MotionSensor, defaultItemProps) + Items.registerBlock(new PowerConverter(defaultProps), Constants.BlockName.PowerConverter, + new Item.Properties().tab(if (!Settings.get.ignorePower) CreativeTab else null)) + Items.registerBlock(new PowerDistributor(defaultProps), Constants.BlockName.PowerDistributor, defaultItemProps) + Items.registerBlock(new Printer(defaultProps), Constants.BlockName.Printer, defaultItemProps) + Items.registerBlock(new Raid(defaultProps), Constants.BlockName.Raid, defaultItemProps) + Items.registerBlock(new Redstone(defaultProps), Constants.BlockName.Redstone, defaultItemProps) + Items.registerBlock(new Relay(defaultProps), Constants.BlockName.Relay, defaultItemProps) + Items.registerBlock(new Screen(defaultProps, Tier.One), Constants.BlockName.ScreenTier1, defaultItemProps) + Items.registerBlock(new Screen(defaultProps, Tier.Three), Constants.BlockName.ScreenTier3, defaultItemProps.rarity(Rarity.RARE)) + Items.registerBlock(new Screen(defaultProps, Tier.Two), Constants.BlockName.ScreenTier2, defaultItemProps.rarity(Rarity.UNCOMMON)) + Items.registerBlock(new Rack(defaultProps), Constants.BlockName.Rack, defaultItemProps) + Items.registerBlock(new Waypoint(defaultProps), Constants.BlockName.Waypoint, defaultItemProps) - Recipes.addBlock(new Adapter(), Constants.BlockName.Adapter, "oc:adapter") - Recipes.addBlock(new Assembler(), Constants.BlockName.Assembler, "oc:assembler") - Recipes.addBlock(new Cable(), Constants.BlockName.Cable, "oc:cable") - Recipes.addBlock(new Capacitor(), Constants.BlockName.Capacitor, "oc:capacitor") - Recipes.addBlock(new Case(Tier.One), Constants.BlockName.CaseTier1, "oc:case1") - Recipes.addBlock(new Case(Tier.Three), Constants.BlockName.CaseTier3, "oc:case3") - Recipes.addBlock(new Case(Tier.Two), Constants.BlockName.CaseTier2, "oc:case2") - Recipes.addBlock(new ChameliumBlock(), Constants.BlockName.ChameliumBlock, "oc:chameliumBlock") - Recipes.addBlock(new Charger(), Constants.BlockName.Charger, "oc:charger") - Recipes.addBlock(new Disassembler(), Constants.BlockName.Disassembler, "oc:disassembler") - Recipes.addBlock(new DiskDrive(), Constants.BlockName.DiskDrive, "oc:diskDrive") - Recipes.addBlock(new Geolyzer(), Constants.BlockName.Geolyzer, "oc:geolyzer") - Recipes.addBlock(new Hologram(Tier.One), Constants.BlockName.HologramTier1, "oc:hologram1") - Recipes.addBlock(new Hologram(Tier.Two), Constants.BlockName.HologramTier2, "oc:hologram2") - Recipes.addBlock(new Keyboard(), Constants.BlockName.Keyboard, "oc:keyboard") - Recipes.addBlock(new MotionSensor(), Constants.BlockName.MotionSensor, "oc:motionSensor") - Recipes.addBlock(new PowerConverter(), Constants.BlockName.PowerConverter, "oc:powerConverter") - Recipes.addBlock(new PowerDistributor(), Constants.BlockName.PowerDistributor, "oc:powerDistributor") - Recipes.addBlock(new Printer(), Constants.BlockName.Printer, "oc:printer") - Recipes.addBlock(new Raid(), Constants.BlockName.Raid, "oc:raid") - Recipes.addBlock(new Redstone(), Constants.BlockName.Redstone, "oc:redstone") - Recipes.addBlock(new Relay(), Constants.BlockName.Relay, "oc:relay") - Recipes.addBlock(new Screen(Tier.One), Constants.BlockName.ScreenTier1, "oc:screen1") - Recipes.addBlock(new Screen(Tier.Three), Constants.BlockName.ScreenTier3, "oc:screen3") - Recipes.addBlock(new Screen(Tier.Two), Constants.BlockName.ScreenTier2, "oc:screen2") - Recipes.addBlock(new Rack(), Constants.BlockName.Rack, "oc:rack", "oc:rack") - Recipes.addBlock(new Waypoint(), Constants.BlockName.Waypoint, "oc:waypoint") - - Items.registerBlock(new Case(Tier.Four), Constants.BlockName.CaseCreative) - Items.registerBlock(new Microcontroller(), Constants.BlockName.Microcontroller) - Items.registerBlock(new Print(), Constants.BlockName.Print) - Items.registerBlock(new RobotAfterimage(), Constants.BlockName.RobotAfterimage) - Items.registerBlock(new RobotProxy(), Constants.BlockName.Robot) + Items.registerBlock(new Case(defaultProps, Tier.Four), Constants.BlockName.CaseCreative, defaultItemProps.rarity(Rarity.EPIC)) + Items.registerBlock(new Microcontroller(defaultProps), Constants.BlockName.Microcontroller, new Item.Properties()) + Items.registerBlock(new Print(Properties.of(Material.METAL).strength(1, 5).noOcclusion.dynamicShape), Constants.BlockName.Print, new Item.Properties()) + Items.registerBlockOnly(new RobotAfterimage(Properties.of(Material.AIR).instabreak.noOcclusion.dynamicShape.air), Constants.BlockName.RobotAfterimage) + Items.registerBlock(new RobotProxy(defaultProps.noOcclusion.dynamicShape), Constants.BlockName.Robot, new Item.Properties()) // v1.5.10 - Recipes.addBlock(new FakeEndstone(), Constants.BlockName.Endstone, "oc:stoneEndstone") + Items.registerBlock(new FakeEndstone(Properties.of(Material.STONE).strength(3, 15)), Constants.BlockName.Endstone, defaultItemProps) // v1.5.14 - Recipes.addBlock(new NetSplitter(), Constants.BlockName.NetSplitter, "oc:netSplitter") + Items.registerBlock(new NetSplitter(defaultProps), Constants.BlockName.NetSplitter, defaultItemProps) // v1.5.16 - Recipes.addBlock(new Transposer(), Constants.BlockName.Transposer, "oc:transposer") + Items.registerBlock(new Transposer(defaultProps), Constants.BlockName.Transposer, defaultItemProps) // v1.7.2 - Recipes.addBlock(new CarpetedCapacitor(), Constants.BlockName.CarpetedCapacitor, "oc:carpetedCapacitor") - } - - private def registerTileEntity(tileEntityClass: Class[_ <: TileEntity], key: String): Unit = { - GameRegistry.registerTileEntity(tileEntityClass, key) + Items.registerBlock(new CarpetedCapacitor(defaultProps), Constants.BlockName.CarpetedCapacitor, defaultItemProps) } } diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index a7e8c5cc7f..ee8c78703d 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -3,6 +3,7 @@ package li.cil.oc.common.init import java.util.concurrent.Callable import li.cil.oc.Constants +import li.cil.oc.CreativeTab import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api.detail.ItemAPI @@ -13,26 +14,25 @@ import li.cil.oc.common.Loot import li.cil.oc.common.Tier import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.common.item.data.DroneData import li.cil.oc.common.item.data.HoverBootsData import li.cil.oc.common.item.data.MicrocontrollerData import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.item.data.TabletData -import li.cil.oc.common.item.traits.Delegate import li.cil.oc.common.item.traits.SimpleItem -import li.cil.oc.common.recipe.Recipes import li.cil.oc.server.machine.luac.LuaStateFactory import net.minecraft.block.Block -import net.minecraft.creativetab.CreativeTabs -import net.minecraft.item.EnumDyeColor +import net.minecraft.item.BlockItem +import net.minecraft.item.DyeColor import net.minecraft.item.Item -import net.minecraft.item.ItemBlock +import net.minecraft.item.Item.Properties +import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.item.Rarity import net.minecraft.util.NonNullList import net.minecraft.util.ResourceLocation -import net.minecraftforge.registries.{GameData} +import net.minecraftforge.common.ToolType +import net.minecraftforge.registries.GameData import scala.collection.mutable import scala.collection.mutable.ArrayBuffer @@ -54,20 +54,13 @@ object Items extends ItemAPI { case _ => null } - def registerBlock(instance: Block, id: String): Block = { + def registerBlockOnly(instance: Block, id: String): Block = { if (!descriptors.contains(id)) { instance match { case simple: SimpleBlock => - instance.setUnlocalizedName("oc." + id) - instance.setRegistryName(id) - GameData.register_impl(instance) - OpenComputers.proxy.registerModel(instance, id) - - val item : Item = new common.block.Item(instance) - item.setUnlocalizedName("oc." + id) - item.setRegistryName(id) - GameData.register_impl(item) - OpenComputers.proxy.registerModel(item, id) + simple.setUnlocalizedName("oc." + id) + simple.setRegistryName(OpenComputers.ID, id) + GameData.register_impl[Block](simple) case _ => } descriptors += id -> new ItemInfo { @@ -77,9 +70,9 @@ object Items extends ItemAPI { override def item = null - override def createItemStack(size: Int): ItemStack = instance match { - case simple: SimpleBlock => simple.createItemStack(size) - case _ => new ItemStack(instance, size) + override def createItemStack(size: Int): ItemStack = { + OpenComputers.log.warn(s"Attempt to get ItemStack for block ${instance} without item form") + ItemStack.EMPTY } } names += instance -> id @@ -87,30 +80,44 @@ object Items extends ItemAPI { instance } - def registerItem[T <: Delegate](delegate: T, id: String): T = { + def registerBlock(instance: Block, id: String, itemProps: Properties): Block = { if (!descriptors.contains(id)) { - OpenComputers.proxy.registerModel(delegate, id) + val itemInst = instance match { + case simple: SimpleBlock => + simple.setUnlocalizedName("oc." + id) + simple.setRegistryName(OpenComputers.ID, id) + GameData.register_impl[Block](simple) + + val item : Item = new common.block.Item(simple, itemProps) + item.setRegistryName(OpenComputers.ID, id) + GameData.register_impl(item) + OpenComputers.proxy.registerModel(item, id) + item + case _ => null.asInstanceOf[Item] + } descriptors += id -> new ItemInfo { override def name: String = id - override def block = null + override def block = instance - override def item: Delegator = delegate.parent + override def item = itemInst - override def createItemStack(size: Int): ItemStack = delegate.createItemStack(size) + override def createItemStack(size: Int): ItemStack = instance match { + case simple: SimpleBlock => simple.createItemStack(size) + case _ => new ItemStack(instance, size) + } } - names += delegate -> id + names += instance -> id } - delegate + instance } def registerItem(instance: Item, id: String): Item = { if (!descriptors.contains(id)) { instance match { case simple: SimpleItem => - simple.setUnlocalizedName("oc." + id) GameData.register_impl(simple.setRegistryName(new ResourceLocation(Settings.resourceDomain, id))) - OpenComputers.proxy.registerModel(instance, id) + OpenComputers.proxy.registerModel(simple, id) case _ => } descriptors += id -> new ItemInfo { @@ -150,17 +157,17 @@ object Items extends ItemAPI { private def getBlockOrItem(stack: ItemStack): Any = if (stack.isEmpty) null - else Delegator.subItem(stack).getOrElse(stack.getItem match { - case block: ItemBlock => block.getBlock + else stack.getItem match { + case block: BlockItem => block.getBlock case item => item - }) + } // ----------------------------------------------------------------------- // val registeredItems: ArrayBuffer[ItemStack] = mutable.ArrayBuffer.empty[ItemStack] - override def registerFloppy(name: String, color: EnumDyeColor, factory: Callable[FileSystem], doRecipeCycling: Boolean): ItemStack = { - val stack = Loot.registerLootDisk(name, color, factory, doRecipeCycling) + override def registerFloppy(name: String, loc: ResourceLocation, color: DyeColor, factory: Callable[FileSystem], doRecipeCycling: Boolean): ItemStack = { + val stack = Loot.registerLootDisk(name, loc, color, factory, doRecipeCycling) registeredItems += stack @@ -168,23 +175,18 @@ object Items extends ItemAPI { } override def registerEEPROM(name: String, code: Array[Byte], data: Array[Byte], readonly: Boolean): ItemStack = { - val nbt = new NBTTagCompound() + val stack = get(Constants.ItemName.EEPROM).createItemStack(1) + val nbt = stack.getOrCreateTagElement(Settings.namespace + "data") if (name != null) { - nbt.setString(Settings.namespace + "label", name.trim.take(24)) + nbt.putString(Settings.namespace + "label", name.trim.take(24)) } if (code != null) { - nbt.setByteArray(Settings.namespace + "eeprom", code.take(Settings.get.eepromSize)) + nbt.putByteArray(Settings.namespace + "eeprom", code.take(Settings.get.eepromSize)) } if (data != null) { - nbt.setByteArray(Settings.namespace + "userdata", data.take(Settings.get.eepromDataSize)) + nbt.putByteArray(Settings.namespace + "userdata", data.take(Settings.get.eepromDataSize)) } - nbt.setBoolean(Settings.namespace + "readonly", readonly) - - val stackNbt = new NBTTagCompound() - stackNbt.setTag(Settings.namespace + "data", nbt) - - val stack = get(Constants.ItemName.EEPROM).createItemStack(1) - stack.setTagCompound(stackNbt) + nbt.putBoolean(Settings.namespace + "readonly", readonly) registeredItems += stack @@ -328,6 +330,8 @@ object Items extends ItemAPI { // ----------------------------------------------------------------------- // + private def defaultProps = new Properties().tab(CreativeTab) + def init() { initMaterials() initTools() @@ -345,214 +349,190 @@ object Items extends ItemAPI { // Crafting materials. private def initMaterials(): Unit = { - val materials = newItem(new item.Delegator(), "material") - - Recipes.addSubItem(new item.CuttingWire(materials), Constants.ItemName.CuttingWire, "oc:materialCuttingWire") - Recipes.addSubItem(new item.Acid(materials), Constants.ItemName.Acid, "oc:materialAcid") - Recipes.addSubItem(new item.RawCircuitBoard(materials), Constants.ItemName.RawCircuitBoard, "oc:materialCircuitBoardRaw") - Recipes.addSubItem(new item.CircuitBoard(materials), Constants.ItemName.CircuitBoard, "oc:materialCircuitBoard") - Recipes.addSubItem(new item.PrintedCircuitBoard(materials), Constants.ItemName.PrintedCircuitBoard, "oc:materialCircuitBoardPrinted") - Recipes.addSubItem(new item.CardBase(materials), Constants.ItemName.Card, "oc:materialCard") - Recipes.addSubItem(new item.Transistor(materials), Constants.ItemName.Transistor, "oc:materialTransistor") - Recipes.addSubItem(new item.Microchip(materials, Tier.One), Constants.ItemName.ChipTier1, "oc:circuitChip1") - Recipes.addSubItem(new item.Microchip(materials, Tier.Two), Constants.ItemName.ChipTier2, "oc:circuitChip2") - Recipes.addSubItem(new item.Microchip(materials, Tier.Three), Constants.ItemName.ChipTier3, "oc:circuitChip3") - Recipes.addSubItem(new item.ALU(materials), Constants.ItemName.Alu, "oc:materialALU") - Recipes.addSubItem(new item.ControlUnit(materials), Constants.ItemName.ControlUnit, "oc:materialCU") - Recipes.addSubItem(new item.Disk(materials), Constants.ItemName.Disk, "oc:materialDisk") - Recipes.addSubItem(new item.Interweb(materials), Constants.ItemName.Interweb, "oc:materialInterweb") - Recipes.addSubItem(new item.ButtonGroup(materials), Constants.ItemName.ButtonGroup, "oc:materialButtonGroup") - Recipes.addSubItem(new item.ArrowKeys(materials), Constants.ItemName.ArrowKeys, "oc:materialArrowKey") - Recipes.addSubItem(new item.NumPad(materials), Constants.ItemName.NumPad, "oc:materialNumPad") - - Recipes.addSubItem(new item.TabletCase(materials, Tier.One), Constants.ItemName.TabletCaseTier1, "oc:tabletCase1") - Recipes.addSubItem(new item.TabletCase(materials, Tier.Two), Constants.ItemName.TabletCaseTier2, "oc:tabletCase2") - registerItem(new item.TabletCase(materials, Tier.Four), Constants.ItemName.TabletCaseCreative) - Recipes.addSubItem(new item.MicrocontrollerCase(materials, Tier.One), Constants.ItemName.MicrocontrollerCaseTier1, "oc:microcontrollerCase1") - Recipes.addSubItem(new item.MicrocontrollerCase(materials, Tier.Two), Constants.ItemName.MicrocontrollerCaseTier2, "oc:microcontrollerCase2") - registerItem(new item.MicrocontrollerCase(materials, Tier.Four), Constants.ItemName.MicrocontrollerCaseCreative) - Recipes.addSubItem(new item.DroneCase(materials, Tier.One), Constants.ItemName.DroneCaseTier1, "oc:droneCase1") - Recipes.addSubItem(new item.DroneCase(materials, Tier.Two), Constants.ItemName.DroneCaseTier2, "oc:droneCase2") - registerItem(new item.DroneCase(materials, Tier.Four), Constants.ItemName.DroneCaseCreative) - - Recipes.addSubItem(new item.InkCartridgeEmpty(materials), Constants.ItemName.InkCartridgeEmpty, "oc:inkCartridgeEmpty") - Recipes.addSubItem(new item.InkCartridge(materials), Constants.ItemName.InkCartridge, "oc:inkCartridge") - Recipes.addSubItem(new item.Chamelium(materials), Constants.ItemName.Chamelium, "oc:chamelium") - - registerItem(new item.DiamondChip(materials), Constants.ItemName.DiamondChip) + registerItem(new item.CuttingWire(defaultProps), Constants.ItemName.CuttingWire) + registerItem(new item.Acid(defaultProps), Constants.ItemName.Acid) + registerItem(new item.RawCircuitBoard(defaultProps), Constants.ItemName.RawCircuitBoard) + registerItem(new item.CircuitBoard(defaultProps), Constants.ItemName.CircuitBoard) + registerItem(new item.PrintedCircuitBoard(defaultProps), Constants.ItemName.PrintedCircuitBoard) + registerItem(new item.CardBase(defaultProps), Constants.ItemName.Card) + registerItem(new item.Transistor(defaultProps), Constants.ItemName.Transistor) + registerItem(new item.Microchip(defaultProps, Tier.One), Constants.ItemName.ChipTier1) + registerItem(new item.Microchip(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.ChipTier2) + registerItem(new item.Microchip(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.ChipTier3) + registerItem(new item.ALU(defaultProps), Constants.ItemName.Alu) + registerItem(new item.ControlUnit(defaultProps), Constants.ItemName.ControlUnit) + registerItem(new item.Disk(defaultProps), Constants.ItemName.Disk) + registerItem(new item.Interweb(defaultProps), Constants.ItemName.Interweb) + registerItem(new item.ButtonGroup(defaultProps), Constants.ItemName.ButtonGroup) + registerItem(new item.ArrowKeys(defaultProps), Constants.ItemName.ArrowKeys) + registerItem(new item.NumPad(defaultProps), Constants.ItemName.NumPad) + + registerItem(new item.TabletCase(defaultProps, Tier.One), Constants.ItemName.TabletCaseTier1) + registerItem(new item.TabletCase(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.TabletCaseTier2) + registerItem(new item.TabletCase(defaultProps.rarity(Rarity.EPIC), Tier.Four), Constants.ItemName.TabletCaseCreative) + registerItem(new item.MicrocontrollerCase(defaultProps, Tier.One), Constants.ItemName.MicrocontrollerCaseTier1) + registerItem(new item.MicrocontrollerCase(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.MicrocontrollerCaseTier2) + registerItem(new item.MicrocontrollerCase(defaultProps.rarity(Rarity.EPIC), Tier.Four), Constants.ItemName.MicrocontrollerCaseCreative) + registerItem(new item.DroneCase(defaultProps, Tier.One), Constants.ItemName.DroneCaseTier1) + registerItem(new item.DroneCase(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.DroneCaseTier2) + registerItem(new item.DroneCase(defaultProps.rarity(Rarity.EPIC), Tier.Four), Constants.ItemName.DroneCaseCreative) + + registerItem(new item.InkCartridgeEmpty(defaultProps.stacksTo(1)), Constants.ItemName.InkCartridgeEmpty) + registerItem(new item.InkCartridge(defaultProps.stacksTo(1).craftRemainder(get(Constants.ItemName.InkCartridgeEmpty).item)), Constants.ItemName.InkCartridge) + registerItem(new item.Chamelium(defaultProps), Constants.ItemName.Chamelium) + + registerItem(new item.DiamondChip(defaultProps), Constants.ItemName.DiamondChip) } + val WrenchType: ToolType = ToolType.get("wrench") + // All kinds of tools. private def initTools(): Unit = { - val tools = newItem(new item.Delegator(), "tool") - - Recipes.addSubItem(new item.Analyzer(tools), Constants.ItemName.Analyzer, "oc:analyzer") - registerItem(new item.Debugger(tools), Constants.ItemName.Debugger) - Recipes.addSubItem(new item.Terminal(tools), Constants.ItemName.Terminal, "oc:terminal") - Recipes.addSubItem(new item.TexturePicker(tools), Constants.ItemName.TexturePicker, "oc:texturePicker") - Recipes.addSubItem(new item.Manual(tools), Constants.ItemName.Manual, "oc:manual") - Recipes.addItem(new item.Wrench(), Constants.ItemName.Wrench, "oc:wrench") + registerItem(new item.Analyzer(defaultProps), Constants.ItemName.Analyzer) + registerItem(new item.Debugger(defaultProps), Constants.ItemName.Debugger) + registerItem(new item.Terminal(defaultProps.stacksTo(1)), Constants.ItemName.Terminal) + registerItem(new item.TexturePicker(defaultProps), Constants.ItemName.TexturePicker) + registerItem(new item.Manual(defaultProps), Constants.ItemName.Manual) + registerItem(new item.Wrench(defaultProps.stacksTo(1).addToolType(WrenchType, 1)), Constants.ItemName.Wrench) // 1.5.11 - Recipes.addItem(new item.HoverBoots(), Constants.ItemName.HoverBoots, "oc:hoverBoots") + registerItem(new item.HoverBoots(defaultProps.stacksTo(1).rarity(Rarity.UNCOMMON).setNoRepair), Constants.ItemName.HoverBoots) // 1.5.18 - Recipes.addSubItem(new item.Nanomachines(tools), Constants.ItemName.Nanomachines, "oc:nanomachines") + registerItem(new item.Nanomachines(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.Nanomachines) } // General purpose components. private def initComponents(): Unit = { - val components = newItem(new item.Delegator(), "component") - - Recipes.addSubItem(new item.CPU(components, Tier.One), Constants.ItemName.CPUTier1, "oc:cpu1") - Recipes.addSubItem(new item.CPU(components, Tier.Two), Constants.ItemName.CPUTier2, "oc:cpu2") - Recipes.addSubItem(new item.CPU(components, Tier.Three), Constants.ItemName.CPUTier3, "oc:cpu3") - - Recipes.addSubItem(new item.ComponentBus(components, Tier.One), Constants.ItemName.ComponentBusTier1, "oc:componentBus1") - Recipes.addSubItem(new item.ComponentBus(components, Tier.Two), Constants.ItemName.ComponentBusTier2, "oc:componentBus2") - Recipes.addSubItem(new item.ComponentBus(components, Tier.Three), Constants.ItemName.ComponentBusTier3, "oc:componentBus3") - - Recipes.addSubItem(new item.Memory(components, Tier.One), Constants.ItemName.RAMTier1, "oc:ram1") - Recipes.addSubItem(new item.Memory(components, Tier.Two), Constants.ItemName.RAMTier2, "oc:ram2") - Recipes.addSubItem(new item.Memory(components, Tier.Three), Constants.ItemName.RAMTier3, "oc:ram3") - Recipes.addSubItem(new item.Memory(components, Tier.Four), Constants.ItemName.RAMTier4, "oc:ram4") - Recipes.addSubItem(new item.Memory(components, Tier.Five), Constants.ItemName.RAMTier5, "oc:ram5") - Recipes.addSubItem(new item.Memory(components, Tier.Six), Constants.ItemName.RAMTier6, "oc:ram6") - - registerItem(new item.Server(components, Tier.Four), Constants.ItemName.ServerCreative) - Recipes.addSubItem(new item.Server(components, Tier.One), Constants.ItemName.ServerTier1, "oc:server1") - Recipes.addSubItem(new item.Server(components, Tier.Two), Constants.ItemName.ServerTier2, "oc:server2") - Recipes.addSubItem(new item.Server(components, Tier.Three), Constants.ItemName.ServerTier3, "oc:server3") + registerItem(new item.CPU(defaultProps, Tier.One), Constants.ItemName.CPUTier1) + registerItem(new item.CPU(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.CPUTier2) + registerItem(new item.CPU(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.CPUTier3) + + registerItem(new item.ComponentBus(defaultProps, Tier.One), Constants.ItemName.ComponentBusTier1) + registerItem(new item.ComponentBus(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.ComponentBusTier2) + registerItem(new item.ComponentBus(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.ComponentBusTier3) + + registerItem(new item.Memory(defaultProps, Tier.One), Constants.ItemName.RAMTier1) + registerItem(new item.Memory(defaultProps, Tier.Two), Constants.ItemName.RAMTier2) + registerItem(new item.Memory(defaultProps.rarity(Rarity.UNCOMMON), Tier.Three), Constants.ItemName.RAMTier3) + registerItem(new item.Memory(defaultProps.rarity(Rarity.UNCOMMON), Tier.Four), Constants.ItemName.RAMTier4) + registerItem(new item.Memory(defaultProps.rarity(Rarity.RARE), Tier.Five), Constants.ItemName.RAMTier5) + registerItem(new item.Memory(defaultProps.rarity(Rarity.RARE), Tier.Six), Constants.ItemName.RAMTier6) + + registerItem(new item.Server(defaultProps.stacksTo(1).rarity(Rarity.EPIC), Tier.Four), Constants.ItemName.ServerCreative) + registerItem(new item.Server(defaultProps.stacksTo(1), Tier.One), Constants.ItemName.ServerTier1) + registerItem(new item.Server(defaultProps.stacksTo(1).rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.ServerTier2) + registerItem(new item.Server(defaultProps.stacksTo(1).rarity(Rarity.RARE), Tier.Three), Constants.ItemName.ServerTier3) // 1.5.10 - Recipes.addSubItem(new item.APU(components, Tier.One), Constants.ItemName.APUTier1, "oc:apu1") - Recipes.addSubItem(new item.APU(components, Tier.Two), Constants.ItemName.APUTier2, "oc:apu2") + registerItem(new item.APU(defaultProps.rarity(Rarity.UNCOMMON), Tier.One), Constants.ItemName.APUTier1) + registerItem(new item.APU(defaultProps.rarity(Rarity.RARE), Tier.Two), Constants.ItemName.APUTier2) // 1.5.12 - registerItem(new item.APU(components, Tier.Three), Constants.ItemName.APUCreative) + registerItem(new item.APU(defaultProps.rarity(Rarity.EPIC), Tier.Three), Constants.ItemName.APUCreative) // 1.6 - Recipes.addSubItem(new item.TerminalServer(components), Constants.ItemName.TerminalServer, "oc:terminalServer") - Recipes.addSubItem(new item.DiskDriveMountable(components), Constants.ItemName.DiskDriveMountable, "oc:diskDriveMountable") + registerItem(new item.TerminalServer(defaultProps.stacksTo(1)), Constants.ItemName.TerminalServer) + registerItem(new item.DiskDriveMountable(defaultProps.stacksTo(1)), Constants.ItemName.DiskDriveMountable) } // Card components. private def initCards(): Unit = { - val cards = newItem(new item.Delegator(), "card") - - registerItem(new item.DebugCard(cards), Constants.ItemName.DebugCard) - Recipes.addSubItem(new item.GraphicsCard(cards, Tier.One), Constants.ItemName.GraphicsCardTier1, "oc:graphicsCard1") - Recipes.addSubItem(new item.GraphicsCard(cards, Tier.Two), Constants.ItemName.GraphicsCardTier2, "oc:graphicsCard2") - Recipes.addSubItem(new item.GraphicsCard(cards, Tier.Three), Constants.ItemName.GraphicsCardTier3, "oc:graphicsCard3") - Recipes.addSubItem(new item.RedstoneCard(cards, Tier.One), Constants.ItemName.RedstoneCardTier1, "oc:redstoneCard1") - Recipes.addSubItem(new item.RedstoneCard(cards, Tier.Two), Constants.ItemName.RedstoneCardTier2, "oc:redstoneCard2") - Recipes.addSubItem(new item.NetworkCard(cards), Constants.ItemName.NetworkCard, "oc:lanCard") - Recipes.addSubItem(new item.WirelessNetworkCard(cards, Tier.Two), Constants.ItemName.WirelessNetworkCardTier2, "oc:wlanCard2") - Recipes.addSubItem(new item.InternetCard(cards), Constants.ItemName.InternetCard, "oc:internetCard") - Recipes.addSubItem(new item.LinkedCard(cards), Constants.ItemName.LinkedCard, "oc:linkedCard") + registerItem(new item.DebugCard(defaultProps), Constants.ItemName.DebugCard) + registerItem(new item.GraphicsCard(defaultProps, Tier.One), Constants.ItemName.GraphicsCardTier1) + registerItem(new item.GraphicsCard(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.GraphicsCardTier2) + registerItem(new item.GraphicsCard(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.GraphicsCardTier3) + registerItem(new item.RedstoneCard(defaultProps, Tier.One), Constants.ItemName.RedstoneCardTier1) + registerItem(new item.RedstoneCard(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.RedstoneCardTier2) + registerItem(new item.NetworkCard(defaultProps), Constants.ItemName.NetworkCard) + registerItem(new item.WirelessNetworkCard(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.WirelessNetworkCardTier2) + registerItem(new item.InternetCard(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.InternetCard) + registerItem(new item.LinkedCard(defaultProps.rarity(Rarity.RARE)), Constants.ItemName.LinkedCard) // 1.5.13 - Recipes.addSubItem(new item.DataCard(cards, Tier.One), Constants.ItemName.DataCardTier1, "oc:dataCard1") + registerItem(new item.DataCard(defaultProps, Tier.One), Constants.ItemName.DataCardTier1) // 1.5.15 - Recipes.addSubItem(new item.DataCard(cards, Tier.Two), Constants.ItemName.DataCardTier2, "oc:dataCard2") - Recipes.addSubItem(new item.DataCard(cards, Tier.Three), Constants.ItemName.DataCardTier3, "oc:dataCard3") + registerItem(new item.DataCard(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.DataCardTier2) + registerItem(new item.DataCard(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.DataCardTier3) } // Upgrade components. private def initUpgrades(): Unit = { - val upgrades = newItem(new item.Delegator(), "upgrade") - - Recipes.addSubItem(new item.UpgradeAngel(upgrades), Constants.ItemName.AngelUpgrade, "oc:angelUpgrade") - Recipes.addSubItem(new item.UpgradeBattery(upgrades, Tier.One), Constants.ItemName.BatteryUpgradeTier1, "oc:batteryUpgrade1") - Recipes.addSubItem(new item.UpgradeBattery(upgrades, Tier.Two), Constants.ItemName.BatteryUpgradeTier2, "oc:batteryUpgrade2") - Recipes.addSubItem(new item.UpgradeBattery(upgrades, Tier.Three), Constants.ItemName.BatteryUpgradeTier3, "oc:batteryUpgrade3") - Recipes.addSubItem(new item.UpgradeChunkloader(upgrades), Constants.ItemName.ChunkloaderUpgrade, "oc:chunkloaderUpgrade") - Recipes.addSubItem(new item.UpgradeContainerCard(upgrades, Tier.One), Constants.ItemName.CardContainerTier1, "oc:cardContainer1") - Recipes.addSubItem(new item.UpgradeContainerCard(upgrades, Tier.Two), Constants.ItemName.CardContainerTier2, "oc:cardContainer2") - Recipes.addSubItem(new item.UpgradeContainerCard(upgrades, Tier.Three), Constants.ItemName.CardContainerTier3, "oc:cardContainer3") - Recipes.addSubItem(new item.UpgradeContainerUpgrade(upgrades, Tier.One), Constants.ItemName.UpgradeContainerTier1, "oc:upgradeContainer1") - Recipes.addSubItem(new item.UpgradeContainerUpgrade(upgrades, Tier.Two), Constants.ItemName.UpgradeContainerTier2, "oc:upgradeContainer2") - Recipes.addSubItem(new item.UpgradeContainerUpgrade(upgrades, Tier.Three), Constants.ItemName.UpgradeContainerTier3, "oc:upgradeContainer3") - Recipes.addSubItem(new item.UpgradeCrafting(upgrades), Constants.ItemName.CraftingUpgrade, "oc:craftingUpgrade") - Recipes.addSubItem(new item.UpgradeDatabase(upgrades, Tier.One), Constants.ItemName.DatabaseUpgradeTier1, "oc:databaseUpgrade1") - Recipes.addSubItem(new item.UpgradeDatabase(upgrades, Tier.Two), Constants.ItemName.DatabaseUpgradeTier2, "oc:databaseUpgrade2") - Recipes.addSubItem(new item.UpgradeDatabase(upgrades, Tier.Three), Constants.ItemName.DatabaseUpgradeTier3, "oc:databaseUpgrade3") - Recipes.addSubItem(new item.UpgradeExperience(upgrades), Constants.ItemName.ExperienceUpgrade, "oc:experienceUpgrade") - Recipes.addSubItem(new item.UpgradeGenerator(upgrades), Constants.ItemName.GeneratorUpgrade, "oc:generatorUpgrade") - Recipes.addSubItem(new item.UpgradeInventory(upgrades), Constants.ItemName.InventoryUpgrade, "oc:inventoryUpgrade") - Recipes.addSubItem(new item.UpgradeInventoryController(upgrades), Constants.ItemName.InventoryControllerUpgrade, "oc:inventoryControllerUpgrade") - Recipes.addSubItem(new item.UpgradeNavigation(upgrades), Constants.ItemName.NavigationUpgrade, "oc:navigationUpgrade") - Recipes.addSubItem(new item.UpgradePiston(upgrades), Constants.ItemName.PistonUpgrade, "oc:pistonUpgrade") - Recipes.addSubItem(new item.UpgradeSign(upgrades), Constants.ItemName.SignUpgrade, "oc:signUpgrade") - Recipes.addSubItem(new item.UpgradeSolarGenerator(upgrades), Constants.ItemName.SolarGeneratorUpgrade, "oc:solarGeneratorUpgrade") - Recipes.addSubItem(new item.UpgradeTank(upgrades), Constants.ItemName.TankUpgrade, "oc:tankUpgrade") - Recipes.addSubItem(new item.UpgradeTankController(upgrades), Constants.ItemName.TankControllerUpgrade, "oc:tankControllerUpgrade") - Recipes.addSubItem(new item.UpgradeTractorBeam(upgrades), Constants.ItemName.TractorBeamUpgrade, "oc:tractorBeamUpgrade") - Recipes.addSubItem(new item.UpgradeLeash(upgrades), Constants.ItemName.LeashUpgrade, "oc:leashUpgrade") + registerItem(new item.UpgradeAngel(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.AngelUpgrade) + registerItem(new item.UpgradeBattery(defaultProps, Tier.One), Constants.ItemName.BatteryUpgradeTier1) + registerItem(new item.UpgradeBattery(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.BatteryUpgradeTier2) + registerItem(new item.UpgradeBattery(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.BatteryUpgradeTier3) + registerItem(new item.UpgradeChunkloader(defaultProps.rarity(Rarity.RARE)), Constants.ItemName.ChunkloaderUpgrade) + registerItem(new item.UpgradeContainerCard(defaultProps, Tier.One), Constants.ItemName.CardContainerTier1) + registerItem(new item.UpgradeContainerCard(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.CardContainerTier2) + registerItem(new item.UpgradeContainerCard(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.CardContainerTier3) + registerItem(new item.UpgradeContainerUpgrade(defaultProps, Tier.One), Constants.ItemName.UpgradeContainerTier1) + registerItem(new item.UpgradeContainerUpgrade(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.UpgradeContainerTier2) + registerItem(new item.UpgradeContainerUpgrade(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.UpgradeContainerTier3) + registerItem(new item.UpgradeCrafting(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.CraftingUpgrade) + registerItem(new item.UpgradeDatabase(defaultProps, Tier.One), Constants.ItemName.DatabaseUpgradeTier1) + registerItem(new item.UpgradeDatabase(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.DatabaseUpgradeTier2) + registerItem(new item.UpgradeDatabase(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.DatabaseUpgradeTier3) + registerItem(new item.UpgradeExperience(defaultProps.rarity(Rarity.RARE)), Constants.ItemName.ExperienceUpgrade) + registerItem(new item.UpgradeGenerator(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.GeneratorUpgrade) + registerItem(new item.UpgradeInventory(defaultProps), Constants.ItemName.InventoryUpgrade) + registerItem(new item.UpgradeInventoryController(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.InventoryControllerUpgrade) + registerItem(new item.UpgradeNavigation(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.NavigationUpgrade) + registerItem(new item.UpgradePiston(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.PistonUpgrade) + registerItem(new item.UpgradeSign(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.SignUpgrade) + registerItem(new item.UpgradeSolarGenerator(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.SolarGeneratorUpgrade) + registerItem(new item.UpgradeTank(defaultProps), Constants.ItemName.TankUpgrade) + registerItem(new item.UpgradeTankController(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.TankControllerUpgrade) + registerItem(new item.UpgradeTractorBeam(defaultProps.rarity(Rarity.RARE)), Constants.ItemName.TractorBeamUpgrade) + registerItem(new item.UpgradeLeash(defaultProps), Constants.ItemName.LeashUpgrade) // 1.5.8 - Recipes.addSubItem(new item.UpgradeHover(upgrades, Tier.One), Constants.ItemName.HoverUpgradeTier1, "oc:hoverUpgrade1") - Recipes.addSubItem(new item.UpgradeHover(upgrades, Tier.Two), Constants.ItemName.HoverUpgradeTier2, "oc:hoverUpgrade2") + registerItem(new item.UpgradeHover(defaultProps, Tier.One), Constants.ItemName.HoverUpgradeTier1) + registerItem(new item.UpgradeHover(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.HoverUpgradeTier2) // 1.6 - Recipes.addSubItem(new item.UpgradeTrading(upgrades), Constants.ItemName.TradingUpgrade, "oc:tradingUpgrade") - Recipes.addSubItem(new item.UpgradeMF(upgrades), Constants.ItemName.MFU, "oc:mfu") + registerItem(new item.UpgradeTrading(defaultProps.rarity(Rarity.UNCOMMON)), Constants.ItemName.TradingUpgrade) + registerItem(new item.UpgradeMF(defaultProps.rarity(Rarity.RARE)), Constants.ItemName.MFU) // 1.7.2 - Recipes.addSubItem(new item.WirelessNetworkCard(upgrades, Tier.One), Constants.ItemName.WirelessNetworkCardTier1, "oc:wlanCard1") - registerItem(new item.ComponentBus(upgrades, Tier.Four), Constants.ItemName.ComponentBusCreative) + registerItem(new item.WirelessNetworkCard(defaultProps, Tier.One), Constants.ItemName.WirelessNetworkCardTier1) + registerItem(new item.ComponentBus(defaultProps.rarity(Rarity.EPIC), Tier.Four), Constants.ItemName.ComponentBusCreative) // 1.8 - Recipes.addSubItem(new item.UpgradeStickyPiston(upgrades), Constants.ItemName.StickyPistonUpgrade, "oc:stickyPistonUpgrade") + registerItem(new item.UpgradeStickyPiston(defaultProps), Constants.ItemName.StickyPistonUpgrade) } // Storage media of all kinds. private def initStorage(): Unit = { - val storage = newItem(new item.Delegator(), "storage") - - Recipes.addSubItem(new item.EEPROM(storage), Constants.ItemName.EEPROM, "oc:eeprom") - Recipes.addSubItem(new item.FloppyDisk(storage), Constants.ItemName.Floppy, "oc:floppy") - Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.One), Constants.ItemName.HDDTier1, "oc:hdd1") - Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.Two), Constants.ItemName.HDDTier2, "oc:hdd2") - Recipes.addSubItem(new item.HardDiskDrive(storage, Tier.Three), Constants.ItemName.HDDTier3, "oc:hdd3") + registerItem(new item.EEPROM(defaultProps), Constants.ItemName.EEPROM) + registerItem(new item.FloppyDisk(defaultProps), Constants.ItemName.Floppy) + registerItem(new item.HardDiskDrive(defaultProps, Tier.One), Constants.ItemName.HDDTier1) + registerItem(new item.HardDiskDrive(defaultProps.rarity(Rarity.UNCOMMON), Tier.Two), Constants.ItemName.HDDTier2) + registerItem(new item.HardDiskDrive(defaultProps.rarity(Rarity.RARE), Tier.Three), Constants.ItemName.HDDTier3) val luaBios = { val code = new Array[Byte](4 * 1024) val count = OpenComputers.getClass.getResourceAsStream(Settings.scriptPath + "bios.lua").read(code) registerEEPROM("EEPROM (Lua BIOS)", code.take(count), null, readonly = false) } - Recipes.addStack(luaBios, Constants.ItemName.LuaBios) + registerStack(luaBios, Constants.ItemName.LuaBios) } // Special purpose items that don't fit into any other category. private def initSpecial(): Unit = { - val misc = newItem(new item.Delegator() { - private def configuredItems = Array( - Items.createConfiguredDrone(), - Items.createConfiguredMicrocontroller(), - Items.createConfiguredRobot(), - Items.createConfiguredTablet(), - Items.createChargedHoverBoots() - ) ++ Loot.disksForClient ++ registeredItems - - override def getSubItems(tab: CreativeTabs, list: NonNullList[ItemStack]): Unit = { - super.getSubItems(tab, list) - if(isInCreativeTab(tab)){ - configuredItems.foreach(list.add) - } - } - }, "misc") - - registerItem(new item.Tablet(misc), Constants.ItemName.Tablet) - registerItem(new item.Drone(misc), Constants.ItemName.Drone) - registerItem(new item.Present(misc), Constants.ItemName.Present) + registerItem(new item.Tablet(defaultProps.stacksTo(1)), Constants.ItemName.Tablet) + registerItem(new item.Drone(defaultProps), Constants.ItemName.Drone) + registerItem(new item.Present(defaultProps), Constants.ItemName.Present) } - private def newItem[T <: Item](item: T, name: String): T = { - item.setUnlocalizedName("oc." + name) - GameData.register_impl(item.setRegistryName(new ResourceLocation(Settings.resourceDomain, name))) - item + def decorateCreativeTab(list: NonNullList[ItemStack]) { + list.add(Items.createConfiguredDrone()) + list.add(Items.createConfiguredMicrocontroller()) + list.add(Items.createConfiguredRobot()) + list.add(Items.createConfiguredTablet()) + Loot.disksForClient.foreach(list.add) + registeredItems.foreach(list.add) } } diff --git a/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala index 7fbdf4be94..8ec5e5f402 100644 --- a/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/ComponentInventory.scala @@ -11,9 +11,9 @@ import li.cil.oc.api.network.Node import li.cil.oc.api.util.Lifecycle import li.cil.oc.integration.opencomputers.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable trait ComponentInventory extends Inventory with network.Environment { @@ -22,7 +22,7 @@ trait ComponentInventory extends Inventory with network.Environment { def components: Array[Option[ManagedEnvironment]] = { if (_components == null && isSizeInventoryReady) { - _components = Array.fill[Option[ManagedEnvironment]](getSizeInventory)(None) + _components = Array.fill[Option[ManagedEnvironment]](getContainerSize)(None) } if (_components == null) Array[Option[ManagedEnvironment]]() else _components } @@ -53,8 +53,8 @@ trait ComponentInventory extends Inventory with network.Environment { // ----------------------------------------------------------------------- // def connectComponents() { - for (slot <- 0 until getSizeInventory if slot >= 0 && slot < components.length) { - val stack = getStackInSlot(slot) + for (slot <- 0 until getContainerSize if slot >= 0 && slot < components.length) { + val stack = getItem(slot) if (!stack.isEmpty && components(slot).isEmpty && isComponentSlot(slot, stack)) { components(slot) = Option(Driver.driverFor(stack)) match { case Some(driver) => @@ -62,7 +62,7 @@ trait ComponentInventory extends Inventory with network.Environment { case Some(component) => applyLifecycleState(component, Lifecycle.LifecycleState.Constructing) try { - component.load(dataTag(driver, stack)) + component.loadData(dataTag(driver, stack)) } catch { case e: Throwable => OpenComputers.log.warn(s"An item component of type '${component.getClass.getName}' (provided by driver '${driver.getClass.getName}') threw an error while loading.", e) @@ -99,20 +99,20 @@ trait ComponentInventory extends Inventory with network.Environment { // ----------------------------------------------------------------------- // - override def save(nbt: NBTTagCompound) = { + override def saveData(nbt: CompoundNBT) { saveComponents() - super.save(nbt) // Save items after updating their tags. + super.saveData(nbt) // Save items after updating their tags. } def saveComponents() { - for (slot <- 0 until getSizeInventory) { - val stack = getStackInSlot(slot) + for (slot <- 0 until getContainerSize) { + val stack = getItem(slot) if (!stack.isEmpty) { if (slot >= components.length) { // isSizeInventoryReady was added to resolve issues where an inventory was used before its // nbt data had been parsed. See https://github.com/MightyPirates/OpenComputers/issues/2522 // If this error is hit again, perhaps another subtype needs to handle nbt loading like Case does - OpenComputers.log.error(s"ComponentInventory components length ${components.length} does not accommodate inventory size ${getSizeInventory}") + OpenComputers.log.error(s"ComponentInventory components length ${components.length} does not accommodate inventory size ${getContainerSize}") return } else { components(slot) match { @@ -128,7 +128,7 @@ trait ComponentInventory extends Inventory with network.Environment { // ----------------------------------------------------------------------- // - override def getInventoryStackLimit = 1 + override def getMaxStackSize = 1 override protected def onItemAdded(slot: Int, stack: ItemStack) = if (slot >= 0 && slot < components.length && isComponentSlot(slot, stack)) { Option(Driver.driverFor(stack)).foreach(driver => @@ -137,7 +137,7 @@ trait ComponentInventory extends Inventory with network.Environment { components(slot) = Some(component) applyLifecycleState(component, Lifecycle.LifecycleState.Constructing) try { - component.load(dataTag(driver, stack)) + component.loadData(dataTag(driver, stack)) } catch { case e: Throwable => OpenComputers.log.warn(s"An item component of type '${component.getClass.getName}' (provided by driver '${driver.getClass.getName}') threw an error while loading.", e) } @@ -194,10 +194,10 @@ trait ComponentInventory extends Inventory with network.Environment { val tag = dataTag(driver, stack) // Clear the tag compound before saving to get the same behavior as // in tile entities (otherwise entries have to be cleared manually). - for (key <- tag.getKeySet.map(_.asInstanceOf[String])) { - tag.removeTag(key) + for (key <- tag.getAllKeys.map(_.asInstanceOf[String])) { + tag.remove(key) } - component.save(tag) + component.saveData(tag) } catch { case e: Throwable => OpenComputers.log.warn(s"An item component of type '${component.getClass.getName}' (provided by driver '${driver.getClass.getName}') threw an error while saving.", e) } diff --git a/src/main/scala/li/cil/oc/common/inventory/DatabaseInventory.scala b/src/main/scala/li/cil/oc/common/inventory/DatabaseInventory.scala index 086ab83424..a1fcba76b4 100644 --- a/src/main/scala/li/cil/oc/common/inventory/DatabaseInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/DatabaseInventory.scala @@ -1,19 +1,30 @@ package li.cil.oc.common.inventory import li.cil.oc.Settings +import li.cil.oc.common.container.ContainerTypes +import li.cil.oc.common.container.{Database => DatabaseContainer} import li.cil.oc.integration.opencomputers.DriverUpgradeDatabase +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack +import net.minecraft.util.text.StringTextComponent -trait DatabaseInventory extends ItemStackInventory { +trait DatabaseInventory extends ItemStackInventory with INamedContainerProvider { def tier: Int = DriverUpgradeDatabase.tier(container) - override def getSizeInventory = Settings.get.databaseEntriesPerTier(tier) + override def getContainerSize = Settings.get.databaseEntriesPerTier(tier) override protected def inventoryName = "database" - override def getInventoryStackLimit = 1 + override def getMaxStackSize = 1 override def getInventoryStackRequired = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack) = stack != container + override def canPlaceItem(slot: Int, stack: ItemStack) = stack != container + + override def getDisplayName = StringTextComponent.EMPTY + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new DatabaseContainer(ContainerTypes.DATABASE, id, playerInventory, container, this, tier) } diff --git a/src/main/scala/li/cil/oc/common/inventory/DiskDriveMountableInventory.scala b/src/main/scala/li/cil/oc/common/inventory/DiskDriveMountableInventory.scala index 58a00ca8da..3bbd9abeac 100644 --- a/src/main/scala/li/cil/oc/common/inventory/DiskDriveMountableInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/DiskDriveMountableInventory.scala @@ -1,21 +1,32 @@ package li.cil.oc.common.inventory import li.cil.oc.api.Driver -import li.cil.oc.common.tileentity import li.cil.oc.common.Slot +import li.cil.oc.common.container.ContainerTypes +import li.cil.oc.common.container.{DiskDrive => DiskDriveContainer} +import li.cil.oc.common.tileentity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack +import net.minecraft.util.text.StringTextComponent -trait DiskDriveMountableInventory extends ItemStackInventory { +trait DiskDriveMountableInventory extends ItemStackInventory with INamedContainerProvider { def tier: Int = 1 - override def getSizeInventory = 1 + override def getContainerSize = 1 override protected def inventoryName = "diskdrive" - override def getInventoryStackLimit = 1 + override def getMaxStackSize = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, classOf[tileentity.DiskDrive]))) match { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, classOf[tileentity.DiskDrive]))) match { case (0, Some(driver)) => driver.slot(stack) == Slot.Floppy case _ => false } + + override def getDisplayName = StringTextComponent.EMPTY + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new DiskDriveContainer(ContainerTypes.DISK_DRIVE, id, playerInventory, this) } diff --git a/src/main/scala/li/cil/oc/common/inventory/Inventory.scala b/src/main/scala/li/cil/oc/common/inventory/Inventory.scala index 74fd0e8bd0..174f2efbb8 100644 --- a/src/main/scala/li/cil/oc/common/inventory/Inventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/Inventory.scala @@ -4,7 +4,9 @@ import li.cil.oc.Settings import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.StackOption import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.TranslationTextComponent import net.minecraftforge.common.util.Constants.NBT trait Inventory extends SimpleInventory { @@ -14,12 +16,12 @@ trait Inventory extends SimpleInventory { // ----------------------------------------------------------------------- // - override def getStackInSlot(slot: Int): ItemStack = - if (slot >= 0 && slot < getSizeInventory) items(slot) + override def getItem(slot: Int): ItemStack = + if (slot >= 0 && slot < getContainerSize) items(slot) else ItemStack.EMPTY - override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = { - if (slot >= 0 && slot < getSizeInventory) { + override def setItem(slot: Int, stack: ItemStack): Unit = { + if (slot >= 0 && slot < getContainerSize) { if (stack.isEmpty && items(slot).isEmpty) { return } @@ -33,8 +35,8 @@ trait Inventory extends SimpleInventory { onItemRemoved(slot, oldStack) } if (!stack.isEmpty && stack.getCount >= getInventoryStackRequired) { - if (stack.getCount > getInventoryStackLimit) { - stack.setCount(getInventoryStackLimit) + if (stack.getCount > getMaxStackSize) { + stack.setCount(getMaxStackSize) } updateItems(slot, stack) } @@ -43,11 +45,11 @@ trait Inventory extends SimpleInventory { onItemAdded(slot, items(slot)) } - markDirty() + setChanged() } } - override def getName: String = Settings.namespace + "container." + inventoryName + override def getName: ITextComponent = new TranslationTextComponent(Settings.namespace + "container." + inventoryName) protected def inventoryName: String = getClass.getSimpleName.toLowerCase @@ -59,26 +61,26 @@ trait Inventory extends SimpleInventory { private final val SlotTag = "slot" private final val ItemTag = "item" - def load(nbt: NBTTagCompound) { - nbt.getTagList(ItemsTag, NBT.TAG_COMPOUND).foreach((tag: NBTTagCompound) => { - if (tag.hasKey(SlotTag)) { + def loadData(nbt: CompoundNBT) { + nbt.getList(ItemsTag, NBT.TAG_COMPOUND).foreach((tag: CompoundNBT) => { + if (tag.contains(SlotTag)) { val slot = tag.getByte(SlotTag) if (slot >= 0 && slot < items.length) { - updateItems(slot, new ItemStack(tag.getCompoundTag(ItemTag))) + updateItems(slot, ItemStack.of(tag.getCompound(ItemTag))) } } }) } - def save(nbt: NBTTagCompound) { + def saveData(nbt: CompoundNBT) { nbt.setNewTagList(ItemsTag, items.zipWithIndex collect { case (stack, slot) if !stack.isEmpty => (stack, slot) } map { case (stack, slot) => - val slotNbt = new NBTTagCompound() - slotNbt.setByte(SlotTag, slot.toByte) - slotNbt.setNewCompoundTag(ItemTag, stack.writeToNBT) + val slotNbt = new CompoundNBT() + slotNbt.putByte(SlotTag, slot.toByte) + slotNbt.setNewCompoundTag(ItemTag, stack.save) }) } diff --git a/src/main/scala/li/cil/oc/common/inventory/InventoryProxy.scala b/src/main/scala/li/cil/oc/common/inventory/InventoryProxy.scala index 020f62ec59..dd036ce1fc 100644 --- a/src/main/scala/li/cil/oc/common/inventory/InventoryProxy.scala +++ b/src/main/scala/li/cil/oc/common/inventory/InventoryProxy.scala @@ -1,6 +1,6 @@ package li.cil.oc.common.inventory -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack import net.minecraft.util.text.ITextComponent @@ -12,59 +12,47 @@ trait InventoryProxy extends IInventory { override def isEmpty: Boolean = inventory.isEmpty - override def getSizeInventory: Int = inventory.getSizeInventory + override def getContainerSize: Int = inventory.getContainerSize - override def getInventoryStackLimit: Int = inventory.getInventoryStackLimit + override def getMaxStackSize: Int = inventory.getMaxStackSize - override def getName: String = inventory.getName + override def stillValid(player: PlayerEntity): Boolean = inventory.stillValid(player) - override def getDisplayName: ITextComponent = inventory.getDisplayName - - override def hasCustomName: Boolean = inventory.hasCustomName - - override def isUsableByPlayer(player: EntityPlayer): Boolean = inventory.isUsableByPlayer(player) - - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = { val offsetSlot = slot + offset - isValidSlot(offsetSlot) && inventory.isItemValidForSlot(offsetSlot, stack) + isValidSlot(offsetSlot) && inventory.canPlaceItem(offsetSlot, stack) } - override def getStackInSlot(slot: Int): ItemStack = { + override def getItem(slot: Int): ItemStack = { val offsetSlot = slot + offset - if (isValidSlot(offsetSlot)) inventory.getStackInSlot(offsetSlot) + if (isValidSlot(offsetSlot)) inventory.getItem(offsetSlot) else ItemStack.EMPTY } - override def decrStackSize(slot: Int, amount: Int): ItemStack = { + override def removeItem(slot: Int, amount: Int): ItemStack = { val offsetSlot = slot + offset - if (isValidSlot(offsetSlot)) inventory.decrStackSize(offsetSlot, amount) + if (isValidSlot(offsetSlot)) inventory.removeItem(offsetSlot, amount) else ItemStack.EMPTY } - override def removeStackFromSlot(slot: Int): ItemStack = { + override def removeItemNoUpdate(slot: Int): ItemStack = { val offsetSlot = slot + offset - if (isValidSlot(offsetSlot)) inventory.removeStackFromSlot(offsetSlot) + if (isValidSlot(offsetSlot)) inventory.removeItemNoUpdate(offsetSlot) else ItemStack.EMPTY } - override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = { + override def setItem(slot: Int, stack: ItemStack): Unit = { val offsetSlot = slot + offset - if (isValidSlot(offsetSlot)) inventory.setInventorySlotContents(offsetSlot, stack) + if (isValidSlot(offsetSlot)) inventory.setItem(offsetSlot, stack) } - override def markDirty(): Unit = inventory.markDirty() - - override def openInventory(player: EntityPlayer): Unit = inventory.openInventory(player) - - override def closeInventory(player: EntityPlayer): Unit = inventory.closeInventory(player) - - override def setField(id: Int, value: Int): Unit = inventory.setField(id, value) + override def setChanged(): Unit = inventory.setChanged() - override def clear(): Unit = inventory.clear() + override def startOpen(player: PlayerEntity): Unit = inventory.startOpen(player) - override def getFieldCount: Int = inventory.getFieldCount + override def stopOpen(player: PlayerEntity): Unit = inventory.stopOpen(player) - override def getField(id: Int): Int = inventory.getField(id) + override def clearContent(): Unit = inventory.clearContent() - private def isValidSlot(slot: Int) = slot >= offset && slot < getSizeInventory + offset + private def isValidSlot(slot: Int) = slot >= offset && slot < getContainerSize + offset } diff --git a/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala index 1c04f22fde..9c621952e7 100644 --- a/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/ItemStackInventory.scala @@ -1,13 +1,13 @@ package li.cil.oc.common.inventory import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT trait ItemStackInventory extends Inventory { // The item stack that provides the inventory. def container: ItemStack - private lazy val inventory = Array.fill[ItemStack](getSizeInventory)(ItemStack.EMPTY) + private lazy val inventory = Array.fill[ItemStack](getContainerSize)(ItemStack.EMPTY) override def items = inventory @@ -24,17 +24,11 @@ trait ItemStackInventory extends Inventory { for (i <- items.indices) { updateItems(i, ItemStack.EMPTY) } - if (!container.hasTagCompound) { - container.setTagCompound(new NBTTagCompound()) - } - load(container.getTagCompound) + loadData(container.getOrCreateTag) } // Write items back to tag. - override def markDirty() { - if (!container.hasTagCompound) { - container.setTagCompound(new NBTTagCompound()) - } - save(container.getTagCompound) + override def setChanged() { + saveData(container.getOrCreateTag) } } diff --git a/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala b/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala index ec03c0faaf..b026ebc8c5 100644 --- a/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/ServerInventory.scala @@ -3,24 +3,33 @@ package li.cil.oc.common.inventory import li.cil.oc.api.Driver import li.cil.oc.api.internal import li.cil.oc.common.InventorySlots +import li.cil.oc.common.container.ContainerTypes +import li.cil.oc.common.container.{Server => ServerContainer} import li.cil.oc.util.ItemUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -trait ServerInventory extends ItemStackInventory { +trait ServerInventory extends ItemStackInventory with INamedContainerProvider { + def rackSlot: Int + def tier: Int = ItemUtils.caseTier(container) max 0 - override def getSizeInventory = InventorySlots.server(tier).length + override def getContainerSize = InventorySlots.server(tier).length override protected def inventoryName = "server" - override def getInventoryStackLimit = 1 + override def getMaxStackSize = 1 - override def isUsableByPlayer(player: EntityPlayer) = false + override def stillValid(player: PlayerEntity) = false - override def isItemValidForSlot(slot: Int, stack: ItemStack) = + override def canPlaceItem(slot: Int, stack: ItemStack) = Option(Driver.driverFor(stack, classOf[internal.Server])).fold(false)(driver => { val provided = InventorySlots.server(tier)(slot) driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier }) + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new ServerContainer(ContainerTypes.SERVER, id, playerInventory, container, this, tier, rackSlot) } diff --git a/src/main/scala/li/cil/oc/common/inventory/SimpleInventory.scala b/src/main/scala/li/cil/oc/common/inventory/SimpleInventory.scala index 34113b7288..36b67e46d6 100644 --- a/src/main/scala/li/cil/oc/common/inventory/SimpleInventory.scala +++ b/src/main/scala/li/cil/oc/common/inventory/SimpleInventory.scala @@ -1,34 +1,35 @@ package li.cil.oc.common.inventory import li.cil.oc.Localization -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack +import net.minecraft.util.INameable import net.minecraft.util.text.ITextComponent -trait SimpleInventory extends IInventory { +trait SimpleInventory extends IInventory with INameable { override def hasCustomName = false - override def getDisplayName: ITextComponent = Localization.localizeLater(getName) + override def getDisplayName: ITextComponent = getName - override def getInventoryStackLimit = 64 + override def getMaxStackSize = 64 // Items required in a slot before it's set to null (for ghost stacks). def getInventoryStackRequired = 1 - override def openInventory(player: EntityPlayer): Unit = {} + override def startOpen(player: PlayerEntity): Unit = {} - override def closeInventory(player: EntityPlayer): Unit = {} + override def stopOpen(player: PlayerEntity): Unit = {} - override def decrStackSize(slot: Int, amount: Int): ItemStack = { - if (slot >= 0 && slot < getSizeInventory) { - (getStackInSlot(slot) match { + override def removeItem(slot: Int, amount: Int): ItemStack = { + if (slot >= 0 && slot < getContainerSize) { + (getItem(slot) match { case stack: ItemStack if stack.getCount - amount < getInventoryStackRequired => - setInventorySlotContents(slot, ItemStack.EMPTY) + setItem(slot, ItemStack.EMPTY) stack case stack: ItemStack => - val result = stack.splitStack(amount) - markDirty() + val result = stack.split(amount) + setChanged() result case _ => ItemStack.EMPTY }) match { @@ -39,24 +40,18 @@ trait SimpleInventory extends IInventory { else ItemStack.EMPTY } - override def removeStackFromSlot(slot: Int) = { - if (slot >= 0 && slot < getSizeInventory) { - val stack = getStackInSlot(slot) - setInventorySlotContents(slot, ItemStack.EMPTY) + override def removeItemNoUpdate(slot: Int) = { + if (slot >= 0 && slot < getContainerSize) { + val stack = getItem(slot) + setItem(slot, ItemStack.EMPTY) stack } else ItemStack.EMPTY } - override def clear(): Unit = { - for (slot <- 0 until getSizeInventory) { - setInventorySlotContents(slot, ItemStack.EMPTY) + override def clearContent(): Unit = { + for (slot <- 0 until getContainerSize) { + setItem(slot, ItemStack.EMPTY) } } - - override def getField(id: Int) = 0 - - override def setField(id: Int, value: Int) {} - - override def getFieldCount = 0 } diff --git a/src/main/scala/li/cil/oc/common/item/ALU.scala b/src/main/scala/li/cil/oc/common/item/ALU.scala index 48daf66d1f..804824109b 100644 --- a/src/main/scala/li/cil/oc/common/item/ALU.scala +++ b/src/main/scala/li/cil/oc/common/item/ALU.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class ALU(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class ALU(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/APU.scala b/src/main/scala/li/cil/oc/common/item/APU.scala index 57835d6871..9672b8c9ad 100644 --- a/src/main/scala/li/cil/oc/common/item/APU.scala +++ b/src/main/scala/li/cil/oc/common/item/APU.scala @@ -1,24 +1,22 @@ package li.cil.oc.common.item import li.cil.oc.common.Tier -import li.cil.oc.util.Rarity -import net.minecraft.item.EnumRarity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem import scala.language.existentials -class APU(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier with traits.CPULike with traits.GPULike { - override val unlocalizedName = super[Delegate].unlocalizedName + tier - - override def rarity(stack: ItemStack): EnumRarity = - if (tier == Tier.Three) Rarity.byTier(Tier.Four) - else super.rarity(stack) +class APU(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier with traits.CPULike with traits.GPULike { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier override def cpuTier = math.min(Tier.Three, tier + 1) override def gpuTier = tier - override protected def tooltipName = Option(super[Delegate].unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) override protected def tooltipData: Seq[Any] = { super[CPULike].tooltipData ++ super[GPULike].tooltipData diff --git a/src/main/scala/li/cil/oc/common/item/Acid.scala b/src/main/scala/li/cil/oc/common/item/Acid.scala index 0ba9912f2e..a567e94d0c 100644 --- a/src/main/scala/li/cil/oc/common/item/Acid.scala +++ b/src/main/scala/li/cil/oc/common/item/Acid.scala @@ -3,36 +3,40 @@ package li.cil.oc.common.item import javax.annotation.Nonnull import li.cil.oc.api -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumAction +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.potion.Potion -import net.minecraft.potion.PotionEffect +import net.minecraft.item.UseAction +import net.minecraft.potion.Effect +import net.minecraft.potion.Effects +import net.minecraft.potion.EffectInstance import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem -class Acid(val parent: Delegator) extends traits.Delegate { - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - player.setActiveHand(if (player.getHeldItemMainhand == stack) EnumHand.MAIN_HAND else EnumHand.OFF_HAND) - ActionResult.newResult(EnumActionResult.SUCCESS, stack) +class Acid(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + player.startUsingItem(if (player.getItemInHand(Hand.MAIN_HAND) == stack) Hand.MAIN_HAND else Hand.OFF_HAND) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } - override def getItemUseAction(stack: ItemStack): EnumAction = EnumAction.DRINK + override def getUseAnimation(stack: ItemStack): UseAction = UseAction.DRINK - override def getMaxItemUseDuration(stack: ItemStack): Int = 32 + override def getUseDuration(stack: ItemStack): Int = 32 - override def onItemUseFinish(stack: ItemStack, world: World, entity: EntityLivingBase): ItemStack = { + override def finishUsingItem(stack: ItemStack, world: World, entity: LivingEntity): ItemStack = { entity match { - case player: EntityPlayer => - if (!world.isRemote) { - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("blindness"), 200)) - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("poison"), 100)) - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("slowness"), 600)) - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("nausea"), 1200)) - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("saturation"), 2000)) + case player: PlayerEntity => + if (!world.isClientSide) { + player.addEffect(new EffectInstance(Effects.BLINDNESS, 200)) + player.addEffect(new EffectInstance(Effects.POISON, 100)) + player.addEffect(new EffectInstance(Effects.MOVEMENT_SLOWDOWN, 600)) + player.addEffect(new EffectInstance(Effects.CONFUSION, 1200)) + player.addEffect(new EffectInstance(Effects.SATURATION, 2000)) // Remove nanomachines if installed. api.Nanomachines.uninstallController(player) diff --git a/src/main/scala/li/cil/oc/common/item/Analyzer.scala b/src/main/scala/li/cil/oc/common/item/Analyzer.scala index 47935d6506..89379cd5b7 100644 --- a/src/main/scala/li/cil/oc/common/item/Analyzer.scala +++ b/src/main/scala/li/cil/oc/common/item/Analyzer.scala @@ -11,46 +11,50 @@ import li.cil.oc.common.tileentity import li.cil.oc.server.PacketSender import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.Util import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.event.entity.player.PlayerInteractEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent object Analyzer { private lazy val analyzer = api.Items.get(Constants.ItemName.Analyzer) @SubscribeEvent def onInteract(e: PlayerInteractEvent.EntityInteract): Unit = { - val player = e.getEntityPlayer - val held = player.getHeldItem(e.getHand) + val player = e.getPlayer + val held = player.getItemInHand(e.getHand) if (api.Items.get(held) == analyzer) { - if (analyze(e.getTarget, player, EnumFacing.DOWN, 0, 0, 0)) { - player.swingArm(e.getHand) + if (analyze(e.getTarget, player, Direction.DOWN, 0, 0, 0)) { + player.swing(e.getHand) e.setCanceled(true) } } } - def analyze(thing: AnyRef, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - val world = player.world + def analyze(thing: AnyRef, player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + val world = player.level thing match { case analyzable: Analyzable => - if (!world.isRemote) { + if (!world.isClientSide) { analyzeNodes(analyzable.onAnalyze(player, side, hitX, hitY, hitZ), player) } true case host: SidedEnvironment => - if (!world.isRemote) { + if (!world.isClientSide) { analyzeNodes(Array(host.sidedNode(side)), player) } true case host: Environment => - if (!world.isRemote) { + if (!world.isClientSide) { analyzeNodes(Array(host.node), player) } true @@ -59,20 +63,20 @@ object Analyzer { } } - private def analyzeNodes(nodes: Array[Node], player: EntityPlayer) = if (nodes != null) for (node <- nodes if node != null) { + private def analyzeNodes(nodes: Array[Node], player: PlayerEntity) = if (nodes != null) for (node <- nodes if node != null) { player match { case _: FakePlayer => // Nope - case playerMP: EntityPlayerMP => + case playerMP: ServerPlayerEntity => if (node != null) node.host match { case machine: Machine => if (machine != null) { if (machine.lastError != null) { - playerMP.sendMessage(Localization.Analyzer.LastError(machine.lastError)) + playerMP.sendMessage(Localization.Analyzer.LastError(machine.lastError), Util.NIL_UUID) } - playerMP.sendMessage(Localization.Analyzer.Components(machine.componentCount, machine.maxComponents)) + playerMP.sendMessage(Localization.Analyzer.Components(machine.componentCount, machine.maxComponents), Util.NIL_UUID) val list = machine.users if (list.nonEmpty) { - playerMP.sendMessage(Localization.Analyzer.Users(list)) + playerMP.sendMessage(Localization.Analyzer.Users(list), Util.NIL_UUID) } } case _ => @@ -80,19 +84,19 @@ object Analyzer { node match { case connector: Connector => if (connector.localBufferSize > 0) { - playerMP.sendMessage(Localization.Analyzer.StoredEnergy(f"${connector.localBuffer}%.2f/${connector.localBufferSize}%.2f")) + playerMP.sendMessage(Localization.Analyzer.StoredEnergy(f"${connector.localBuffer}%.2f/${connector.localBufferSize}%.2f"), Util.NIL_UUID) } - playerMP.sendMessage(Localization.Analyzer.TotalEnergy(f"${connector.globalBuffer}%.2f/${connector.globalBufferSize}%.2f")) + playerMP.sendMessage(Localization.Analyzer.TotalEnergy(f"${connector.globalBuffer}%.2f/${connector.globalBufferSize}%.2f"), Util.NIL_UUID) case _ => } node match { case component: Component => - playerMP.sendMessage(Localization.Analyzer.ComponentName(component.name)) + playerMP.sendMessage(Localization.Analyzer.ComponentName(component.name), Util.NIL_UUID) case _ => } val address = node.address() if (address != null && !address.isEmpty) { - playerMP.sendMessage(Localization.Analyzer.Address(address)) + playerMP.sendMessage(Localization.Analyzer.Address(address), Util.NIL_UUID) PacketSender.sendAnalyze(address, playerMP) } case _ => @@ -100,32 +104,29 @@ object Analyzer { } } -class Analyzer(val parent: Delegator) extends traits.Delegate { - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (player.isSneaking && stack.hasTagCompound) { - stack.getTagCompound.removeTag(Settings.namespace + "clipboard") - if (stack.getTagCompound.hasNoTags) { - stack.setTagCompound(null) - } +class Analyzer(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (player.isCrouching && stack.hasTag) { + stack.removeTagKey(Settings.namespace + "clipboard") } - super.onItemRightClick(stack, world, player) + super.use(stack, world, player) } - override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = { - val world = player.getEntityWorld - world.getTileEntity(position) match { + override def onItemUse(stack: ItemStack, player: PlayerEntity, position: BlockPosition, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = { + val world = player.level + world.getBlockEntity(position) match { case screen: tileentity.Screen if side == screen.facing => - if (player.isSneaking) { + if (player.isCrouching) { screen.copyToAnalyzer(hitX, hitY, hitZ) } - else if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "clipboard")) { - if (!world.isRemote) { - screen.origin.buffer.clipboard(stack.getTagCompound.getString(Settings.namespace + "clipboard"), player) + else if (stack.hasTag && stack.getTag.contains(Settings.namespace + "clipboard")) { + if (!world.isClientSide) { + screen.origin.buffer.clipboard(stack.getTag.getString(Settings.namespace + "clipboard"), player) } true } else false - case _ => Analyzer.analyze(position.world.get.getTileEntity(position), player, side, hitX, hitY, hitZ) + case _ => Analyzer.analyze(position.world.get.getBlockEntity(position), player, side, hitX, hitY, hitZ) } } } diff --git a/src/main/scala/li/cil/oc/common/item/ArrowKeys.scala b/src/main/scala/li/cil/oc/common/item/ArrowKeys.scala index fef4d0850f..7a63055992 100644 --- a/src/main/scala/li/cil/oc/common/item/ArrowKeys.scala +++ b/src/main/scala/li/cil/oc/common/item/ArrowKeys.scala @@ -1,5 +1,9 @@ package li.cil.oc.common.item -class ArrowKeys(val parent: Delegator) extends traits.Delegate { +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class ArrowKeys(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { override protected def tooltipName = None } diff --git a/src/main/scala/li/cil/oc/common/item/ButtonGroup.scala b/src/main/scala/li/cil/oc/common/item/ButtonGroup.scala index c6450d41d3..030f51a438 100644 --- a/src/main/scala/li/cil/oc/common/item/ButtonGroup.scala +++ b/src/main/scala/li/cil/oc/common/item/ButtonGroup.scala @@ -1,5 +1,9 @@ package li.cil.oc.common.item -class ButtonGroup(val parent: Delegator) extends traits.Delegate { +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class ButtonGroup(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { override protected def tooltipName = None } diff --git a/src/main/scala/li/cil/oc/common/item/CPU.scala b/src/main/scala/li/cil/oc/common/item/CPU.scala index bc8aacce44..9a7c6e4974 100644 --- a/src/main/scala/li/cil/oc/common/item/CPU.scala +++ b/src/main/scala/li/cil/oc/common/item/CPU.scala @@ -1,11 +1,16 @@ package li.cil.oc.common.item +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + import scala.language.existentials -class CPU(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier with traits.CPULike { - override val unlocalizedName = super.unlocalizedName + tier +class CPU(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier with traits.CPULike { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier override def cpuTier = tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) } diff --git a/src/main/scala/li/cil/oc/common/item/CardBase.scala b/src/main/scala/li/cil/oc/common/item/CardBase.scala index dfb3362ae3..af0667686a 100644 --- a/src/main/scala/li/cil/oc/common/item/CardBase.scala +++ b/src/main/scala/li/cil/oc/common/item/CardBase.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class CardBase(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class CardBase(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/Chamelium.scala b/src/main/scala/li/cil/oc/common/item/Chamelium.scala index 7486f2fac4..8be92fd7c0 100644 --- a/src/main/scala/li/cil/oc/common/item/Chamelium.scala +++ b/src/main/scala/li/cil/oc/common/item/Chamelium.scala @@ -1,33 +1,37 @@ package li.cil.oc.common.item import li.cil.oc.Settings -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumAction +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.potion.Potion -import net.minecraft.potion.PotionEffect +import net.minecraft.item.UseAction +import net.minecraft.potion.Effect +import net.minecraft.potion.Effects +import net.minecraft.potion.EffectInstance import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem -class Chamelium(val parent: Delegator) extends traits.Delegate { - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { +class Chamelium(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { if (Settings.get.chameliumEdible) { - player.setActiveHand(if (player.getHeldItemMainhand == stack) EnumHand.MAIN_HAND else EnumHand.OFF_HAND) + player.startUsingItem(if (player.getItemInHand(Hand.MAIN_HAND) == stack) Hand.MAIN_HAND else Hand.OFF_HAND) } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } - override def getItemUseAction(stack: ItemStack): EnumAction = EnumAction.EAT + override def getUseAnimation(stack: ItemStack): UseAction = UseAction.EAT - override def getMaxItemUseDuration(stack: ItemStack): Int = 32 + override def getUseDuration(stack: ItemStack): Int = 32 - override def onItemUseFinish(stack: ItemStack, world: World, player: EntityLivingBase): ItemStack = { - if (!world.isRemote) { - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("invisibility"), 100, 0)) - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("blindness"), 200, 0)) + override def finishUsingItem(stack: ItemStack, world: World, player: LivingEntity): ItemStack = { + if (!world.isClientSide) { + player.addEffect(new EffectInstance(Effects.INVISIBILITY, 100, 0)) + player.addEffect(new EffectInstance(Effects.BLINDNESS, 200, 0)) } stack.shrink(1) if (stack.getCount > 0) stack diff --git a/src/main/scala/li/cil/oc/common/item/CircuitBoard.scala b/src/main/scala/li/cil/oc/common/item/CircuitBoard.scala index b24c2a0321..b88c00c253 100644 --- a/src/main/scala/li/cil/oc/common/item/CircuitBoard.scala +++ b/src/main/scala/li/cil/oc/common/item/CircuitBoard.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class CircuitBoard(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class CircuitBoard(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/ComponentBus.scala b/src/main/scala/li/cil/oc/common/item/ComponentBus.scala index 867fe47fe6..2c33d2adc3 100644 --- a/src/main/scala/li/cil/oc/common/item/ComponentBus.scala +++ b/src/main/scala/li/cil/oc/common/item/ComponentBus.scala @@ -1,21 +1,16 @@ package li.cil.oc.common.item import li.cil.oc.Settings -import li.cil.oc.common.Tier -import li.cil.oc.util.Rarity -import net.minecraft.item.EnumRarity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem -class ComponentBus(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class ComponentBus(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - // Because the driver considers the creative bus to be tier 3, the superclass - // will believe it has T3 rarity. We override that here. - override def rarity(stack: ItemStack): EnumRarity = - if (tier == Tier.Four) Rarity.byTier(Tier.Four) - else super.rarity(stack) - - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) override protected def tooltipData = Seq(Settings.get.cpuComponentSupport(tier)) } diff --git a/src/main/scala/li/cil/oc/common/item/ControlUnit.scala b/src/main/scala/li/cil/oc/common/item/ControlUnit.scala index b9eab26ab0..637cdcca40 100644 --- a/src/main/scala/li/cil/oc/common/item/ControlUnit.scala +++ b/src/main/scala/li/cil/oc/common/item/ControlUnit.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class ControlUnit(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class ControlUnit(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/CustomModel.scala b/src/main/scala/li/cil/oc/common/item/CustomModel.scala index 33a52b337a..e8a114d05c 100644 --- a/src/main/scala/li/cil/oc/common/item/CustomModel.scala +++ b/src/main/scala/li/cil/oc/common/item/CustomModel.scala @@ -1,18 +1,18 @@ package li.cil.oc.common.item -import net.minecraft.client.renderer.block.model.ModelResourceLocation +import net.minecraft.client.renderer.model.ModelResourceLocation import net.minecraft.item.ItemStack import net.minecraftforge.client.event.ModelBakeEvent -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn trait CustomModel { - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) def getModelLocation(stack: ItemStack): ModelResourceLocation - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) def registerModelLocations(): Unit = {} - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) def bakeModels(bakeEvent: ModelBakeEvent): Unit = {} } diff --git a/src/main/scala/li/cil/oc/common/item/CuttingWire.scala b/src/main/scala/li/cil/oc/common/item/CuttingWire.scala index 6814a420d9..07399930aa 100644 --- a/src/main/scala/li/cil/oc/common/item/CuttingWire.scala +++ b/src/main/scala/li/cil/oc/common/item/CuttingWire.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class CuttingWire(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class CuttingWire(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/DataCard.scala b/src/main/scala/li/cil/oc/common/item/DataCard.scala index 69479fd05a..488ea499ac 100644 --- a/src/main/scala/li/cil/oc/common/item/DataCard.scala +++ b/src/main/scala/li/cil/oc/common/item/DataCard.scala @@ -1,5 +1,10 @@ package li.cil.oc.common.item -class DataCard(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class DataCard(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/DebugCard.scala b/src/main/scala/li/cil/oc/common/item/DebugCard.scala index 278f1009d7..d12821576c 100644 --- a/src/main/scala/li/cil/oc/common/item/DebugCard.scala +++ b/src/main/scala/li/cil/oc/common/item/DebugCard.scala @@ -6,43 +6,48 @@ import li.cil.oc.Settings import li.cil.oc.Settings.DebugCardAccess import li.cil.oc.common.item.data.DebugCardData import li.cil.oc.server.component.{DebugCard => CDebugCard} -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand -import net.minecraft.util.text.TextComponentString +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand +import net.minecraft.util.Util +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem -class DebugCard(val parent: Delegator) extends traits.Delegate { - override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = { +class DebugCard(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[ITextComponent]): Unit = { super.tooltipExtended(stack, tooltip) val data = new DebugCardData(stack) - data.access.foreach(access => tooltip.add(s"§8${access.player}§r")) + data.access.foreach(access => tooltip.add(new StringTextComponent(s"§8${access.player}§r"))) } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (!world.isRemote && player.isSneaking) { + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (!world.isClientSide && player.isCrouching) { val data = new DebugCardData(stack) val name = player.getName if (data.access.exists(_.player == name)) data.access = None else data.access = - Some(CDebugCard.AccessContext(name, Settings.get.debugCardAccess match { - case wl: DebugCardAccess.Whitelist => wl.nonce(name) match { + Some(CDebugCard.AccessContext(name.getString, Settings.get.debugCardAccess match { + case wl: DebugCardAccess.Whitelist => wl.nonce(name.getString) match { case Some(n) => n case None => - player.sendMessage(new TextComponentString("§cYou are not whitelisted to use debug card")) - player.swingArm(EnumHand.MAIN_HAND) - return new ActionResult[ItemStack](EnumActionResult.FAIL, stack) + player.sendMessage(new StringTextComponent("§cYou are not whitelisted to use debug card"), Util.NIL_UUID) + player.swing(Hand.MAIN_HAND) + return new ActionResult[ItemStack](ActionResultType.FAIL, stack) } case _ => "" })) - data.save(stack) - player.swingArm(EnumHand.MAIN_HAND) + data.saveData(stack) + player.swing(Hand.MAIN_HAND) } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } } diff --git a/src/main/scala/li/cil/oc/common/item/Debugger.scala b/src/main/scala/li/cil/oc/common/item/Debugger.scala index 7b20cdba63..bb6daeb819 100644 --- a/src/main/scala/li/cil/oc/common/item/Debugger.scala +++ b/src/main/scala/li/cil/oc/common/item/Debugger.scala @@ -5,31 +5,34 @@ import li.cil.oc.api import li.cil.oc.api.network._ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraftforge.common.util.FakePlayer +import net.minecraftforge.common.extensions.IForgeItem -class Debugger(val parent: Delegator) extends traits.Delegate { - override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = { +class Debugger(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def onItemUse(stack: ItemStack, player: PlayerEntity, position: BlockPosition, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = { val world = position.world.get player match { case _: FakePlayer => false // Nope - case realPlayer: EntityPlayerMP => - world.getTileEntity(position) match { + case realPlayer: ServerPlayerEntity => + world.getBlockEntity(position) match { case host: SidedEnvironment => - if (!world.isRemote) { + if (!world.isClientSide) { Debugger.reconnect(Array(host.sidedNode(side))) } true case host: Environment => - if (!world.isRemote) { + if (!world.isClientSide) { Debugger.reconnect(Array(host.node)) } true case _ => - if (!world.isRemote) { + if (!world.isClientSide) { Debugger.node.remove() } true diff --git a/src/main/scala/li/cil/oc/common/item/Delegator.scala b/src/main/scala/li/cil/oc/common/item/Delegator.scala deleted file mode 100644 index fbbdca01f9..0000000000 --- a/src/main/scala/li/cil/oc/common/item/Delegator.scala +++ /dev/null @@ -1,245 +0,0 @@ -package li.cil.oc.common.item - -import java.util -import li.cil.oc.CreativeTab -import li.cil.oc.OpenComputers -import li.cil.oc.api.driver -import li.cil.oc.api.driver.item.Chargeable -import li.cil.oc.api.event.RobotRenderEvent.MountPoint -import li.cil.oc.api.internal.Robot -import li.cil.oc.client.renderer.item.UpgradeRenderer -import li.cil.oc.common.item.traits.Delegate -import li.cil.oc.integration.opencomputers.{Item => OpenComputersItem} -import li.cil.oc.util.BlockPosition -import net.minecraft.client.util.ITooltipFlag -import net.minecraft.creativetab.CreativeTabs -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumAction -import net.minecraft.item.EnumRarity -import net.minecraft.item.Item -import net.minecraft.item.ItemStack -import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand -import net.minecraft.util.NonNullList -import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess -import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -import scala.collection.mutable -import scala.collection.mutable.ArrayBuffer - -object Delegator { - def subItem(stack: ItemStack): Option[Delegate] = - if (!stack.isEmpty) stack.getItem match { - case delegator: Delegator => delegator.subItem(stack.getItemDamage) - case _ => None - } - else None -} - -class Delegator extends Item with driver.item.UpgradeRenderer with Chargeable { - setHasSubtypes(true) - setCreativeTab(CreativeTab) - - // ----------------------------------------------------------------------- // - // SubItem - // ----------------------------------------------------------------------- // - - override def getItemStackLimit(stack: ItemStack): Int = - Delegator.subItem(stack) match { - case Some(subItem) => OpenComputersItem.address(stack) match { - case Some(address) => 1 - case _ => subItem.maxStackSize - } - case _ => maxStackSize - } - - val subItems: ArrayBuffer[Delegate] = mutable.ArrayBuffer.empty[traits.Delegate] - - def add(subItem: traits.Delegate): Int = { - val itemId = subItems.length - subItems += subItem - itemId - } - - def subItem(damage: Int): Option[Delegate] = - damage match { - case itemId if itemId >= 0 && itemId < subItems.length => Some(subItems(itemId)) - case _ => None - } - - override def getSubItems(tab: CreativeTabs, list: NonNullList[ItemStack]) { - // Workaround for MC's untyped lists... - if(isInCreativeTab(tab)){ - subItems.indices.filter(subItems(_).showInItemList). - map(subItems(_).createItemStack()). - sortBy(_.getUnlocalizedName). - foreach(list.add) - } - } - - // ----------------------------------------------------------------------- // - // Item - // ----------------------------------------------------------------------- // - - override def getUnlocalizedName(stack: ItemStack): String = - Delegator.subItem(stack) match { - case Some(subItem) => "item.oc." + subItem.unlocalizedName - case _ => getUnlocalizedName - } - - override def isBookEnchantable(itemA: ItemStack, itemB: ItemStack): Boolean = false - - override def getRarity(stack: ItemStack): EnumRarity = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.rarity(stack) - case _ => EnumRarity.COMMON - } - -// override def getColorFromItemStack(stack: ItemStack, pass: Int) = -// Delegator.subItem(stack) match { -// case Some(subItem) => subItem.color(stack, pass) -// case _ => super.getColorFromItemStack(stack, pass) -// } - - override def getContainerItem(stack: ItemStack): ItemStack = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.getContainerItem(stack) - case _ => super.getContainerItem(stack) - } - - override def hasContainerItem(stack: ItemStack): Boolean = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.hasContainerItem(stack) - case _ => super.hasContainerItem(stack) - } - - // ----------------------------------------------------------------------- // - - override def doesSneakBypassUse(stack: ItemStack, world: IBlockAccess, pos: BlockPos, player: EntityPlayer): Boolean = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.doesSneakBypassUse(world, pos, player) - case _ => super.doesSneakBypassUse(stack, world, pos, player) - } - - override def onItemUseFirst(player: EntityPlayer, world: World, pos: BlockPos, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float, hand: EnumHand): EnumActionResult = - player.getHeldItem(hand) match { - case stack:ItemStack => Delegator.subItem(stack) match { - case Some(subItem) => subItem.onItemUseFirst(stack, player, BlockPosition(pos, world), side, hitX, hitY, hitZ) - case _ => super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand) - } - case _ => super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand) - } - - override def onItemUse(player: EntityPlayer, world: World, pos: BlockPos, hand: EnumHand, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): EnumActionResult = - player.getHeldItem(hand) match { - case stack: ItemStack => Delegator.subItem(stack) match { - case Some(subItem) => if (subItem.onItemUse(stack, player, BlockPosition(pos, world), side, hitX, hitY, hitZ)) EnumActionResult.SUCCESS else EnumActionResult.PASS - case _ => super.onItemUse(player, world, pos, hand, side, hitX, hitY, hitZ) - } - case _ => super.onItemUse(player, world, pos, hand, side, hitX, hitY, hitZ) - } - - override def onItemRightClick(world: World, player: EntityPlayer, hand: EnumHand): ActionResult[ItemStack] = - player.getHeldItem(hand) match { - case stack: ItemStack => Delegator.subItem(stack) match { - case Some(subItem) => subItem.onItemRightClick(stack, world, player) - case _ => super.onItemRightClick(world, player, hand) - } - case _ => super.onItemRightClick(world, player, hand) - } - - // ----------------------------------------------------------------------- // - - override def onItemUseFinish(stack: ItemStack, world: World, entity: EntityLivingBase): ItemStack = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.onItemUseFinish(stack, world, entity) - case _ => super.onItemUseFinish(stack, world, entity) - } - - override def getItemUseAction(stack: ItemStack): EnumAction = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.getItemUseAction(stack) - case _ => super.getItemUseAction(stack) - } - - override def getMaxItemUseDuration(stack: ItemStack): Int = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.getMaxItemUseDuration(stack) - case _ => super.getMaxItemUseDuration(stack) - } - - override def onPlayerStoppedUsing(stack: ItemStack, world: World, entity: EntityLivingBase, timeLeft: Int): Unit = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.onPlayerStoppedUsing(stack, entity, timeLeft) - case _ => super.onPlayerStoppedUsing(stack, world, entity, timeLeft) - } - - def internalGetItemStackDisplayName(stack: ItemStack): String = super.getItemStackDisplayName(stack) - - override def getItemStackDisplayName(stack: ItemStack): String = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.displayName(stack) match { - case Some(name) => name - case _ => super.getItemStackDisplayName(stack) - } - case _ => super.getItemStackDisplayName(stack) - } - - @SideOnly(Side.CLIENT) - override def addInformation(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - super.addInformation(stack, world, tooltip, flag) - Delegator.subItem(stack) match { - case Some(subItem) => try subItem.tooltipLines(stack, world, tooltip, flag) catch { - case t: Throwable => OpenComputers.log.warn("Error in item tooltip.", t) - } - case _ => // Nothing to add. - } - } - - override def getDurabilityForDisplay(stack: ItemStack): Double = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.durability(stack) - case _ => super.getDurabilityForDisplay(stack) - } - - override def showDurabilityBar(stack: ItemStack): Boolean = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.showDurabilityBar(stack) - case _ => super.showDurabilityBar(stack) - } - - override def onUpdate(stack: ItemStack, world: World, player: Entity, slot: Int, selected: Boolean): Unit = - Delegator.subItem(stack) match { - case Some(subItem) => subItem.update(stack, world, player, slot, selected) - case _ => super.onUpdate(stack, world, player, slot, selected) - } - - override def toString: String = getUnlocalizedName - - // ----------------------------------------------------------------------- // - - def canCharge(stack: ItemStack): Boolean = - Delegator.subItem(stack) match { - case Some(subItem: Chargeable) => true - case _ => false - } - - def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = - Delegator.subItem(stack) match { - case Some(subItem: Chargeable) => subItem.charge(stack, amount, simulate) - case _ => amount - } - - // ----------------------------------------------------------------------- // - - override def computePreferredMountPoint(stack: ItemStack, robot: Robot, availableMountPoints: util.Set[String]): String = UpgradeRenderer.preferredMountPoint(stack, availableMountPoints) - - override def render(stack: ItemStack, mountPoint: MountPoint, robot: Robot, pt: Float): Unit = UpgradeRenderer.render(stack, mountPoint) -} diff --git a/src/main/scala/li/cil/oc/common/item/DiamondChip.scala b/src/main/scala/li/cil/oc/common/item/DiamondChip.scala index 813d7cae4d..28cc9b7cac 100644 --- a/src/main/scala/li/cil/oc/common/item/DiamondChip.scala +++ b/src/main/scala/li/cil/oc/common/item/DiamondChip.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class DiamondChip(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class DiamondChip(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/Disk.scala b/src/main/scala/li/cil/oc/common/item/Disk.scala index 38ba6f950e..afd23bb19d 100644 --- a/src/main/scala/li/cil/oc/common/item/Disk.scala +++ b/src/main/scala/li/cil/oc/common/item/Disk.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class Disk(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class Disk(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/DiskDriveMountable.scala b/src/main/scala/li/cil/oc/common/item/DiskDriveMountable.scala index 5f275155a9..36b89310b1 100644 --- a/src/main/scala/li/cil/oc/common/item/DiskDriveMountable.scala +++ b/src/main/scala/li/cil/oc/common/item/DiskDriveMountable.scala @@ -1,21 +1,28 @@ package li.cil.oc.common.item import li.cil.oc.OpenComputers -import li.cil.oc.common.GuiType -import net.minecraft.entity.player.EntityPlayer +import li.cil.oc.common.container.ContainerTypes +import li.cil.oc.common.inventory.DiskDriveMountableInventory +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.util.{ActionResult, EnumActionResult, EnumHand} +import net.minecraft.util.{ActionResult, ActionResultType, Hand} import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem -class DiskDriveMountable(val parent: Delegator) extends traits.Delegate { - override def maxStackSize = 1 +class DiskDriveMountable(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def use(stack: ItemStack, world: World, player: PlayerEntity) = { + if (!world.isClientSide) player match { + case srvPlr: ServerPlayerEntity => ContainerTypes.openDiskDriveGui(srvPlr, new DiskDriveMountableInventory { + override def container: ItemStack = stack - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer) = { - // Open the GUI immediately on the client, too, to avoid the player - // changing the current slot before it actually opens, which can lead to - // desynchronization of the player inventory. - player.openGui(OpenComputers, GuiType.DiskDriveMountable.id, world, 0, 0, 0) - player.swingArm(EnumHand.MAIN_HAND) - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + override def stillValid(player: PlayerEntity) = player == srvPlr + }) + case _ => + } + player.swing(Hand.MAIN_HAND) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } } diff --git a/src/main/scala/li/cil/oc/common/item/Drone.scala b/src/main/scala/li/cil/oc/common/item/Drone.scala index e6df199904..13a19402d1 100644 --- a/src/main/scala/li/cil/oc/common/item/Drone.scala +++ b/src/main/scala/li/cil/oc/common/item/Drone.scala @@ -6,61 +6,67 @@ import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.client.KeyBindings import li.cil.oc.client.renderer.block.DroneModel -import li.cil.oc.common.entity import li.cil.oc.common.item.data.DroneData -import li.cil.oc.integration.util.ItemBlacklist +import li.cil.oc.common.entity import li.cil.oc.server.agent import li.cil.oc.util.BlockPosition import li.cil.oc.util.Rarity -import net.minecraft.client.renderer.block.model.ModelResourceLocation -import net.minecraft.entity.player.EntityPlayer +import li.cil.oc.util.Tooltip +import net.minecraft.client.renderer.model.ModelResourceLocation +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.NonNullList +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraftforge.client.event.ModelBakeEvent -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -class Drone(val parent: Delegator) extends traits.Delegate with CustomModel { - ItemBlacklist.hide(this) +import net.minecraftforge.common.extensions.IForgeItem +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn - showInItemList = false - - @SideOnly(Side.CLIENT) +class Drone(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with CustomModel { + @OnlyIn(Dist.CLIENT) override def getModelLocation(stack: ItemStack) = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.ItemName.Drone, "inventory") - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def bakeModels(bakeEvent: ModelBakeEvent): Unit = { - bakeEvent.getModelRegistry.putObject(getModelLocation(createItemStack()), DroneModel) + bakeEvent.getModelRegistry.put(getModelLocation(createItemStack()), DroneModel) } - override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = { + override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[ITextComponent]): Unit = { if (KeyBindings.showExtendedTooltips) { val info = new DroneData(stack) for (component <- info.components if !component.isEmpty) { - tooltip.add("- " + component.getDisplayName) + tooltip.add(new StringTextComponent("- " + component.getHoverName.getString).setStyle(Tooltip.DefaultStyle)) } } } - override def rarity(stack: ItemStack) = { + override def getRarity(stack: ItemStack) = { val data = new DroneData(stack) Rarity.byTier(data.tier) } - override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = { + // Must be assembled to be usable so we hide it in the item list. + override def fillItemCategory(tab: ItemGroup, list: NonNullList[ItemStack]) {} + + override def onItemUse(stack: ItemStack, player: PlayerEntity, position: BlockPosition, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = { val world = position.world.get - if (!world.isRemote) { - val drone = new entity.Drone(world) + if (!world.isClientSide) { + val drone = entity.EntityTypes.DRONE.create(world) player match { case fakePlayer: agent.Player => drone.ownerName = fakePlayer.agent.ownerName drone.ownerUUID = fakePlayer.agent.ownerUUID case _ => - drone.ownerName = player.getName + drone.ownerName = player.getName.getString drone.ownerUUID = player.getGameProfile.getId } drone.initializeAfterPlacement(stack, player, position.offset(hitX * 1.1f, hitY * 1.1f, hitZ * 1.1f)) - world.spawnEntity(drone) + world.addFreshEntity(drone) } stack.shrink(1) true diff --git a/src/main/scala/li/cil/oc/common/item/DroneCase.scala b/src/main/scala/li/cil/oc/common/item/DroneCase.scala index 8564082602..5cab2ea526 100644 --- a/src/main/scala/li/cil/oc/common/item/DroneCase.scala +++ b/src/main/scala/li/cil/oc/common/item/DroneCase.scala @@ -1,11 +1,15 @@ package li.cil.oc.common.item +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem -class DroneCase(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class DroneCase(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier override protected def tierFromDriver(stack: ItemStack) = tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/EEPROM.scala b/src/main/scala/li/cil/oc/common/item/EEPROM.scala index b39cd96913..c19dde357e 100644 --- a/src/main/scala/li/cil/oc/common/item/EEPROM.scala +++ b/src/main/scala/li/cil/oc/common/item/EEPROM.scala @@ -2,24 +2,29 @@ package li.cil.oc.common.item import li.cil.oc.Settings import li.cil.oc.util.BlockPosition -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IWorldReader +import net.minecraftforge.common.extensions.IForgeItem -class EEPROM(val parent: Delegator) extends traits.Delegate { - override def displayName(stack: ItemStack): Option[String] = { - if (stack.hasTagCompound) { - val tag = stack.getTagCompound - if (tag.hasKey(Settings.namespace + "data")) { - val data = tag.getCompoundTag(Settings.namespace + "data") - if (data.hasKey(Settings.namespace + "label")) { - return Some(data.getString(Settings.namespace + "label")) +class EEPROM(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def getName(stack: ItemStack): ITextComponent = { + if (stack.hasTag) { + val tag = stack.getTag + if (tag.contains(Settings.namespace + "data")) { + val data = tag.getCompound(Settings.namespace + "data") + if (data.contains(Settings.namespace + "label")) { + return new StringTextComponent(data.getString(Settings.namespace + "label")) } } } - super.displayName(stack) + super.getName(stack) } - override def doesSneakBypassUse(world: IBlockAccess, pos: BlockPos, player: EntityPlayer): Boolean = true + override def doesSneakBypassUse(stack: ItemStack, world: IWorldReader, pos: BlockPos, player: PlayerEntity): Boolean = true } diff --git a/src/main/scala/li/cil/oc/common/item/FloppyDisk.scala b/src/main/scala/li/cil/oc/common/item/FloppyDisk.scala index c122216b9b..31732aa3d0 100644 --- a/src/main/scala/li/cil/oc/common/item/FloppyDisk.scala +++ b/src/main/scala/li/cil/oc/common/item/FloppyDisk.scala @@ -2,45 +2,49 @@ package li.cil.oc.common.item import li.cil.oc.Constants import li.cil.oc.Settings -import li.cil.oc.util.Color -import net.minecraft.client.renderer.block.model.ModelBakery -import net.minecraft.client.renderer.block.model.ModelResourceLocation -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.client.renderer.model.ModelBakery +import net.minecraft.client.renderer.model.ModelResourceLocation +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.DyeColor +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.world.IWorldReader +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.client.model.ModelLoader +import net.minecraftforge.common.extensions.IForgeItem -class FloppyDisk(val parent: Delegator) extends traits.Delegate with CustomModel with traits.FileSystemLike { +class FloppyDisk(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with CustomModel with traits.FileSystemLike { // Necessary for anonymous subclasses used for loot disks. - override def unlocalizedName = "floppydisk" + unlocalizedName = "floppydisk" val kiloBytes = Settings.get.floppySize - @SideOnly(Side.CLIENT) - private def modelLocationFromDyeName(name: String) = { - new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.ItemName.Floppy + "_" + name, "inventory") + @OnlyIn(Dist.CLIENT) + private def modelLocationFromDyeName(dye: DyeColor) = { + new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.ItemName.Floppy + "_" + dye.getName, "inventory") } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def getModelLocation(stack: ItemStack): ModelResourceLocation = { val dyeIndex = - if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "color")) - stack.getTagCompound.getInteger(Settings.namespace + "color") + if (stack.hasTag && stack.getTag.contains(Settings.namespace + "color")) + stack.getTag.getInt(Settings.namespace + "color") else - 8 - modelLocationFromDyeName(Color.dyes(dyeIndex max 0 min 15)) + DyeColor.LIGHT_GRAY.getId + modelLocationFromDyeName(DyeColor.byId(dyeIndex max 0 min 15)) } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def registerModelLocations(): Unit = { - for (dyeName <- Color.dyes) { - val location = modelLocationFromDyeName(dyeName) - ModelBakery.registerItemVariants(parent, new ResourceLocation(location.getResourceDomain + ":" + location.getResourcePath)) + for (dye <- DyeColor.values) { + val location = modelLocationFromDyeName(dye) + ModelLoader.addSpecialModel(location) } } - override def doesSneakBypassUse(world: IBlockAccess, pos: BlockPos, player: EntityPlayer): Boolean = true + override def doesSneakBypassUse(stack: ItemStack, world: IWorldReader, pos: BlockPos, player: PlayerEntity): Boolean = true } diff --git a/src/main/scala/li/cil/oc/common/item/GraphicsCard.scala b/src/main/scala/li/cil/oc/common/item/GraphicsCard.scala index 0fb7074615..777e1ddda5 100644 --- a/src/main/scala/li/cil/oc/common/item/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/common/item/GraphicsCard.scala @@ -1,9 +1,14 @@ package li.cil.oc.common.item -class GraphicsCard(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier with traits.GPULike { - override val unlocalizedName = super.unlocalizedName + tier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class GraphicsCard(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier with traits.GPULike { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier override def gpuTier = tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala b/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala index 2f6ba39c42..d4457b5131 100644 --- a/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala +++ b/src/main/scala/li/cil/oc/common/item/HardDiskDrive.scala @@ -1,20 +1,28 @@ package li.cil.oc.common.item import li.cil.oc.Settings +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraftforge.common.extensions.IForgeItem + +class HardDiskDrive(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier with traits.FileSystemLike { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier -class HardDiskDrive(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier with traits.FileSystemLike { - override val unlocalizedName: String = super.unlocalizedName + tier val kiloBytes: Int = Settings.get.hddSizes(tier) val platterCount: Int = Settings.get.hddPlatterCounts(tier) - override def displayName(stack: ItemStack): Some[String] = { - val localizedName = parent.internalGetItemStackDisplayName(stack) - Some(if (kiloBytes >= 1024) { - localizedName + s" (${kiloBytes / 1024}MB)" + override def getName(stack: ItemStack): ITextComponent = { + val localizedName = super.getName(stack).copy() + if (kiloBytes >= 1024) { + localizedName.append(s" (${kiloBytes / 1024}MB)") } else { - localizedName + s" (${kiloBytes}KB)" - }) + localizedName.append(s" (${kiloBytes}KB)") + } + localizedName } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala index 722a44059d..7d61f9defa 100644 --- a/src/main/scala/li/cil/oc/common/item/HoverBoots.scala +++ b/src/main/scala/li/cil/oc/common/item/HoverBoots.scala @@ -2,30 +2,34 @@ package li.cil.oc.common.item import li.cil.oc.Settings import li.cil.oc.client.renderer.item.HoverBootRenderer +import li.cil.oc.common.init.Items import li.cil.oc.common.item.data.HoverBootsData import li.cil.oc.util.ItemColorizer -import net.minecraft.block.BlockCauldron -import net.minecraft.client.model.ModelBiped -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.init.Blocks -import net.minecraft.inventory.EntityEquipmentSlot -import net.minecraft.item.EnumRarity -import net.minecraft.item.ItemArmor +import net.minecraft.block.Blocks +import net.minecraft.block.CauldronBlock +import net.minecraft.client.renderer.entity.model.BipedModel +import net.minecraft.inventory.EquipmentSlotType +import net.minecraft.item.ArmorItem +import net.minecraft.item.ArmorMaterial +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack -import net.minecraft.potion.Potion -import net.minecraft.potion.PotionEffect +import net.minecraft.item.Rarity +import net.minecraft.entity.Entity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.item.ItemEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.potion.Effect +import net.minecraft.potion.Effects +import net.minecraft.potion.EffectInstance +import net.minecraft.util.NonNullList import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, EntityEquipmentSlot.FEET) with traits.SimpleItem with traits.Chargeable { - setNoRepair() - - override def getRarity(stack: ItemStack): EnumRarity = EnumRarity.UNCOMMON +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.common.extensions.IForgeItem +class HoverBoots(props: Properties) extends ArmorItem(ArmorMaterial.DIAMOND, EquipmentSlotType.FEET, props) with IForgeItem with traits.SimpleItem with traits.Chargeable { override def maxCharge(stack: ItemStack): Double = Settings.get.bufferHoverBoots override def getCharge(stack: ItemStack): Double = @@ -34,7 +38,7 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, EntityEqu override def setCharge(stack: ItemStack, amount: Double): Unit = { val data = new HoverBootsData(stack) data.charge = math.min(maxCharge(stack), math.max(0, amount)) - data.save(stack) + data.saveData(stack) } override def canCharge(stack: ItemStack): Boolean = true @@ -43,45 +47,50 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, EntityEqu val data = new HoverBootsData(stack) traits.Chargeable.applyCharge(amount, data.charge, Settings.get.bufferHoverBoots, used => if (!simulate) { data.charge += used - data.save(stack) + data.saveData(stack) }) } - @SideOnly(Side.CLIENT) - override def getArmorModel(entityLiving: EntityLivingBase, itemStack: ItemStack, armorSlot: EntityEquipmentSlot, _default: ModelBiped): ModelBiped = { - if (armorSlot == armorType) { + override def fillItemCategory(tab: ItemGroup, list: NonNullList[ItemStack]): Unit = { + super.fillItemCategory(tab, list) + if (allowdedIn(tab)) list.add(Items.createChargedHoverBoots()) + } + + @OnlyIn(Dist.CLIENT) + override def getArmorModel[A <: BipedModel[_]](entityLiving: LivingEntity, itemStack: ItemStack, armorSlot: EquipmentSlotType, _default: A): A = { + if (armorSlot == slot) { HoverBootRenderer.lightColor = if (ItemColorizer.hasColor(itemStack)) ItemColorizer.getColor(itemStack) else 0x66DD55 - HoverBootRenderer + HoverBootRenderer.asInstanceOf[A] } else super.getArmorModel(entityLiving, itemStack, armorSlot, _default) } - override def getArmorTexture(stack: ItemStack, entity: Entity, slot: EntityEquipmentSlot, subType: String): String = { - if (entity.world.isRemote) HoverBootRenderer.texture.toString + override def getArmorTexture(stack: ItemStack, entity: Entity, slot: EquipmentSlotType, subType: String): String = { + if (entity.level.isClientSide) HoverBootRenderer.texture.toString else null } - override def onArmorTick(world: World, player: EntityPlayer, stack: ItemStack): Unit = { - super.onArmorTick(world, player, stack) - if (!Settings.get.ignorePower && player.getActivePotionEffect(Potion.getPotionFromResourceLocation("slowness")) == null && getCharge(stack) == 0) { - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("slowness"), 20, 1)) + override def onArmorTick(stack: ItemStack, world: World, player: PlayerEntity): Unit = { + super.onArmorTick(stack, world, player) + if (!Settings.get.ignorePower && player.getEffect(Effects.MOVEMENT_SLOWDOWN) == null && getCharge(stack) == 0) { + player.addEffect(new EffectInstance(Effects.MOVEMENT_SLOWDOWN, 20, 1)) } } - override def onEntityItemUpdate(entity: EntityItem): Boolean = { - if (entity != null && entity.world != null && !entity.world.isRemote && ItemColorizer.hasColor(entity.getItem)) { - val pos = entity.getPosition - val state = entity.world.getBlockState(pos) + override def onEntityItemUpdate(stack: ItemStack, entity: ItemEntity): Boolean = { + if (entity != null && entity.level != null && !entity.level.isClientSide && ItemColorizer.hasColor(stack)) { + val pos = entity.blockPosition + val state = entity.level.getBlockState(pos) if (state.getBlock == Blocks.CAULDRON) { - val level = state.getValue(BlockCauldron.LEVEL).toInt + val level = state.getValue(CauldronBlock.LEVEL).toInt if (level > 0) { - ItemColorizer.removeColor(entity.getItem) - entity.world.setBlockState(pos, state.withProperty(BlockCauldron.LEVEL, Int.box(level - 1)), 3) + ItemColorizer.removeColor(stack) + entity.level.setBlock(pos, state.setValue(CauldronBlock.LEVEL, Int.box(level - 1)), 3) return true } } } - super.onEntityItemUpdate(entity) + super.onEntityItemUpdate(stack, entity) } override def showDurabilityBar(stack: ItemStack): Boolean = true @@ -97,7 +106,7 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, EntityEqu override def isDamaged(stack: ItemStack): Boolean = true // Contradictory as it may seem with the above, this avoids actual damage value changing. - override def isDamageable: Boolean = false + override def canBeDepleted: Boolean = false override def setDamage(stack: ItemStack, damage: Int): Unit = { // Subtract energy when taking damage instead of actually damaging the item. diff --git a/src/main/scala/li/cil/oc/common/item/InkCartridge.scala b/src/main/scala/li/cil/oc/common/item/InkCartridge.scala index 1477984fae..a85168a066 100644 --- a/src/main/scala/li/cil/oc/common/item/InkCartridge.scala +++ b/src/main/scala/li/cil/oc/common/item/InkCartridge.scala @@ -1,18 +1,7 @@ package li.cil.oc.common.item -import li.cil.oc.Constants -import li.cil.oc.api -import net.minecraft.item.ItemStack +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem -class InkCartridge(val parent: Delegator) extends traits.Delegate { - override def maxStackSize = 1 - - override def getContainerItem(stack: ItemStack): ItemStack = { - if (api.Items.get(stack) == api.Items.get(Constants.ItemName.InkCartridge)) - api.Items.get(Constants.ItemName.InkCartridgeEmpty).createItemStack(1) - else - super.getContainerItem(stack) - } - - override def hasContainerItem(stack: ItemStack): Boolean = true -} +class InkCartridge(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/InkCartridgeEmpty.scala b/src/main/scala/li/cil/oc/common/item/InkCartridgeEmpty.scala index f7a879ca21..cb68dc3dd3 100644 --- a/src/main/scala/li/cil/oc/common/item/InkCartridgeEmpty.scala +++ b/src/main/scala/li/cil/oc/common/item/InkCartridgeEmpty.scala @@ -1,5 +1,7 @@ package li.cil.oc.common.item -class InkCartridgeEmpty(val parent: Delegator) extends traits.Delegate { - override def maxStackSize = 1 -} +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class InkCartridgeEmpty(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/InternetCard.scala b/src/main/scala/li/cil/oc/common/item/InternetCard.scala index 5c43ebc508..fc0cc79e24 100644 --- a/src/main/scala/li/cil/oc/common/item/InternetCard.scala +++ b/src/main/scala/li/cil/oc/common/item/InternetCard.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class InternetCard(val parent: Delegator) extends traits.Delegate with traits.ItemTier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class InternetCard(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/common/item/Interweb.scala b/src/main/scala/li/cil/oc/common/item/Interweb.scala index 7e1fdbc78c..bd13b0f0cc 100644 --- a/src/main/scala/li/cil/oc/common/item/Interweb.scala +++ b/src/main/scala/li/cil/oc/common/item/Interweb.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class Interweb(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class Interweb(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/LinkedCard.scala b/src/main/scala/li/cil/oc/common/item/LinkedCard.scala index 11a24cccec..e97ba02620 100644 --- a/src/main/scala/li/cil/oc/common/item/LinkedCard.scala +++ b/src/main/scala/li/cil/oc/common/item/LinkedCard.scala @@ -5,24 +5,38 @@ import java.util import li.cil.oc.Settings import li.cil.oc.util.Tooltip import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.common.extensions.IForgeItem -class LinkedCard(val parent: Delegator) extends traits.Delegate with traits.ItemTier { - override def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data")) { - val data = stack.getTagCompound.getCompoundTag(Settings.namespace + "data") - if (data.hasKey(Settings.namespace + "tunnel")) { +import scala.collection.convert.ImplicitConversionsToScala._ + +class LinkedCard(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) + if (stack.hasTag && stack.getTag.contains(Settings.namespace + "data")) { + val data = stack.getTag.getCompound(Settings.namespace + "data") + if (data.contains(Settings.namespace + "tunnel")) { val channel = data.getString(Settings.namespace + "tunnel") if (channel.length > 13) { - tooltip.addAll(Tooltip.get(unlocalizedName + "_channel", channel.substring(0, 13) + "...")) + for (curr <- Tooltip.get(unlocalizedName + "_channel", channel.substring(0, 13) + "...")) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } else { - tooltip.addAll(Tooltip.get(unlocalizedName + "_channel", channel)) + for (curr <- Tooltip.get(unlocalizedName + "_channel", channel)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } } } - super.tooltipLines(stack, world, tooltip, flag) } } diff --git a/src/main/scala/li/cil/oc/common/item/Manual.scala b/src/main/scala/li/cil/oc/common/item/Manual.scala index bafecea267..5a4c667338 100644 --- a/src/main/scala/li/cil/oc/common/item/Manual.scala +++ b/src/main/scala/li/cil/oc/common/item/Manual.scala @@ -6,38 +6,43 @@ import li.cil.oc.OpenComputers import li.cil.oc.api import li.cil.oc.util.BlockPosition import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumFacing +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.util.text.TextFormatting import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.common.extensions.IForgeItem -class Manual(val parent: Delegator) extends traits.Delegate { - @SideOnly(Side.CLIENT) - override def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag): Unit = { - tooltip.add(TextFormatting.DARK_GRAY.toString + "v" + OpenComputers.Version) - super.tooltipLines(stack, world, tooltip, flag) +class Manual(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) + tooltip.add(new StringTextComponent(TextFormatting.DARK_GRAY.toString + "v" + OpenComputers.get.Version)) } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (world.isRemote) { - if (player.isSneaking) { + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (world.isClientSide) { + if (player.isCrouching) { api.Manual.reset() } api.Manual.openFor(player) } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } - override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - val world = player.getEntityWorld + override def onItemUse(stack: ItemStack, player: PlayerEntity, position: BlockPosition, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + val world = player.level api.Manual.pathFor(world, position.toBlockPos) match { case path: String => - if (world.isRemote) { + if (world.isClientSide) { api.Manual.openFor(player) api.Manual.reset() api.Manual.navigate(path) diff --git a/src/main/scala/li/cil/oc/common/item/Memory.scala b/src/main/scala/li/cil/oc/common/item/Memory.scala index 9eb4652b15..f3c1a66e27 100644 --- a/src/main/scala/li/cil/oc/common/item/Memory.scala +++ b/src/main/scala/li/cil/oc/common/item/Memory.scala @@ -1,7 +1,12 @@ package li.cil.oc.common.item -class Memory(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem - override protected def tooltipName = Option(super.unlocalizedName) +class Memory(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier + + override protected def tooltipName = Option(unlocalizedName) } diff --git a/src/main/scala/li/cil/oc/common/item/Microchip.scala b/src/main/scala/li/cil/oc/common/item/Microchip.scala index 42fbc20ecf..cee66f9f10 100644 --- a/src/main/scala/li/cil/oc/common/item/Microchip.scala +++ b/src/main/scala/li/cil/oc/common/item/Microchip.scala @@ -1,12 +1,13 @@ package li.cil.oc.common.item -import li.cil.oc.util.Rarity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem -class Microchip(val parent: Delegator, val tier: Int) extends traits.Delegate { - override val unlocalizedName = super.unlocalizedName + tier +class Microchip(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - override protected def tooltipName = Option(super.unlocalizedName) - - override def rarity(stack: ItemStack) = Rarity.byTier(tier) + override protected def tooltipName = Option(unlocalizedName) } diff --git a/src/main/scala/li/cil/oc/common/item/MicrocontrollerCase.scala b/src/main/scala/li/cil/oc/common/item/MicrocontrollerCase.scala index 70d092b68d..8483e67594 100644 --- a/src/main/scala/li/cil/oc/common/item/MicrocontrollerCase.scala +++ b/src/main/scala/li/cil/oc/common/item/MicrocontrollerCase.scala @@ -1,11 +1,15 @@ package li.cil.oc.common.item +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem -class MicrocontrollerCase(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class MicrocontrollerCase(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier override protected def tierFromDriver(stack: ItemStack) = tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) } diff --git a/src/main/scala/li/cil/oc/common/item/Nanomachines.scala b/src/main/scala/li/cil/oc/common/item/Nanomachines.scala index f7e179bd8a..d4e132a4a7 100644 --- a/src/main/scala/li/cil/oc/common/item/Nanomachines.scala +++ b/src/main/scala/li/cil/oc/common/item/Nanomachines.scala @@ -7,45 +7,48 @@ import li.cil.oc.api import li.cil.oc.common.item.data.NanomachineData import li.cil.oc.common.nanomachines.ControllerImpl import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumAction -import net.minecraft.item.EnumRarity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraft.item.Rarity +import net.minecraft.item.UseAction import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.common.extensions.IForgeItem -class Nanomachines(val parent: Delegator) extends traits.Delegate { - override def rarity(stack: ItemStack): EnumRarity = EnumRarity.UNCOMMON - - @SideOnly(Side.CLIENT) - override def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag): Unit = { - super.tooltipLines(stack, world, tooltip, flag) - if (stack.hasTagCompound) { +class Nanomachines(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) + if (stack.hasTag) { val data = new NanomachineData(stack) if (!Strings.isNullOrEmpty(data.uuid)) { - tooltip.add("§8" + data.uuid.substring(0, 13) + "...§7") + tooltip.add(new StringTextComponent("§8" + data.uuid.substring(0, 13) + "...§7")) } } } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - player.setActiveHand(if (player.getHeldItemMainhand == stack) EnumHand.MAIN_HAND else EnumHand.OFF_HAND) - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + player.startUsingItem(if (player.getItemInHand(Hand.MAIN_HAND) == stack) Hand.MAIN_HAND else Hand.OFF_HAND) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } - override def getItemUseAction(stack: ItemStack): EnumAction = EnumAction.EAT + override def getUseAnimation(stack: ItemStack): UseAction = UseAction.EAT - override def getMaxItemUseDuration(stack: ItemStack): Int = 32 + override def getUseDuration(stack: ItemStack): Int = 32 - override def onItemUseFinish(stack: ItemStack, world: World, entity: EntityLivingBase): ItemStack = { + override def finishUsingItem(stack: ItemStack, world: World, entity: LivingEntity): ItemStack = { entity match { - case player: EntityPlayer => - if (!world.isRemote) { + case player: PlayerEntity => + if (!world.isClientSide) { val data = new NanomachineData(stack) // Re-install to get new address, make sure we're configured. @@ -57,7 +60,7 @@ class Nanomachines(val parent: Delegator) extends traits.Delegate { if (!Strings.isNullOrEmpty(data.uuid)) { controller.uuid = data.uuid } - controller.configuration.load(nbt) + controller.configuration.loadData(nbt) case _ => controller.reconfigure() } case controller => controller.reconfigure() // Huh. diff --git a/src/main/scala/li/cil/oc/common/item/NetworkCard.scala b/src/main/scala/li/cil/oc/common/item/NetworkCard.scala index 89b64cf928..6fabdf6c28 100644 --- a/src/main/scala/li/cil/oc/common/item/NetworkCard.scala +++ b/src/main/scala/li/cil/oc/common/item/NetworkCard.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class NetworkCard(val parent: Delegator) extends traits.Delegate with traits.ItemTier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class NetworkCard(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/common/item/NumPad.scala b/src/main/scala/li/cil/oc/common/item/NumPad.scala index 57d50028e1..775b312da5 100644 --- a/src/main/scala/li/cil/oc/common/item/NumPad.scala +++ b/src/main/scala/li/cil/oc/common/item/NumPad.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class NumPad(val parent: Delegator) extends traits.Delegate \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class NumPad(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/Present.scala b/src/main/scala/li/cil/oc/common/item/Present.scala index 62684d1c5f..5a612f8cd1 100644 --- a/src/main/scala/li/cil/oc/common/item/Present.scala +++ b/src/main/scala/li/cil/oc/common/item/Present.scala @@ -7,33 +7,42 @@ import li.cil.oc.OpenComputers import li.cil.oc.api import li.cil.oc.util.InventoryUtils import li.cil.oc.util.ItemUtils -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.init.SoundEvents +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack +import net.minecraft.item.crafting.RecipeManager import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult +import net.minecraft.util.ActionResultType +import net.minecraft.util.NonNullList import net.minecraft.util.SoundCategory +import net.minecraft.util.SoundEvents import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem import scala.collection.mutable -class Present(val parent: Delegator) extends traits.Delegate { - showInItemList = false +class Present(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def fillItemCategory(tab: ItemGroup, list: NonNullList[ItemStack]) {} - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { if (stack.getCount > 0) { stack.shrink(1) - if (!world.isRemote) { - world.playSound(player, player.posX, player.posY, player.posZ, SoundEvents.ENTITY_PLAYER_LEVELUP, SoundCategory.MASTER, 0.2f, 1f) + if (!world.isClientSide) { + world.playSound(player, player.getX, player.getY, player.getZ, SoundEvents.PLAYER_LEVELUP, SoundCategory.MASTER, 0.2f, 1f) + Present.recipeManager = world.getRecipeManager val present = Present.nextPresent() InventoryUtils.addToPlayerInventory(present, player) } } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } } object Present { + private var recipeManager: RecipeManager = null + private lazy val Presents = { val result = mutable.ArrayBuffer.empty[ItemStack] @@ -42,7 +51,7 @@ object Present { if (item != null) { val stack = item.createItemStack(1) // Only if it can be crafted (wasn't disabled in the config). - if (ItemUtils.getIngredients(stack).nonEmpty) { + if (ItemUtils.getIngredients(recipeManager, stack).nonEmpty) { for (i <- 0 until weight) result += stack } } @@ -134,5 +143,5 @@ object Present { private val rng = new Random() - def nextPresent(): ItemStack = Presents(rng.nextInt(Presents.length)).copy() + private def nextPresent(): ItemStack = Presents(rng.nextInt(Presents.length)).copy() } diff --git a/src/main/scala/li/cil/oc/common/item/PrintedCircuitBoard.scala b/src/main/scala/li/cil/oc/common/item/PrintedCircuitBoard.scala index 37a0097b3c..d1d68e5ac7 100644 --- a/src/main/scala/li/cil/oc/common/item/PrintedCircuitBoard.scala +++ b/src/main/scala/li/cil/oc/common/item/PrintedCircuitBoard.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class PrintedCircuitBoard(val parent: Delegator) extends traits.Delegate +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class PrintedCircuitBoard(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem diff --git a/src/main/scala/li/cil/oc/common/item/RawCircuitBoard.scala b/src/main/scala/li/cil/oc/common/item/RawCircuitBoard.scala index 5e52e7416e..b6d6483e31 100644 --- a/src/main/scala/li/cil/oc/common/item/RawCircuitBoard.scala +++ b/src/main/scala/li/cil/oc/common/item/RawCircuitBoard.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class RawCircuitBoard(val parent: Delegator) extends traits.Delegate \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class RawCircuitBoard(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/RedstoneCard.scala b/src/main/scala/li/cil/oc/common/item/RedstoneCard.scala index db8c0c34e6..69ee306719 100644 --- a/src/main/scala/li/cil/oc/common/item/RedstoneCard.scala +++ b/src/main/scala/li/cil/oc/common/item/RedstoneCard.scala @@ -3,23 +3,21 @@ package li.cil.oc.common.item import java.util import li.cil.oc.common.Tier +import li.cil.oc.integration.opencomputers.ModOpenComputers +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack +import net.minecraft.util.NonNullList +import net.minecraftforge.common.extensions.IForgeItem -class RedstoneCard(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class RedstoneCard(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) - // Note: T2 is enabled in mod integration, if it makes sense. - showInItemList = tier == Tier.One - - override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) { - super.tooltipExtended(stack, tooltip) - if (tier == Tier.Two) { - // TODO Generic system for redstone integration modules to register in a list of tooltip lines. - // if (Mods.MOD_NAME.isAvailable) { - // tooltip.addAll(Tooltip.get(super.unlocalizedName + ".MOD_NAME")) - // } - } + override def fillItemCategory(tab: ItemGroup, list: NonNullList[ItemStack]) { + if (tier == Tier.One || ModOpenComputers.hasRedstoneCardT2) super.fillItemCategory(tab, list) } } diff --git a/src/main/scala/li/cil/oc/common/item/Server.scala b/src/main/scala/li/cil/oc/common/item/Server.scala index 953fa1001d..64258a9fc3 100644 --- a/src/main/scala/li/cil/oc/common/item/Server.scala +++ b/src/main/scala/li/cil/oc/common/item/Server.scala @@ -4,61 +4,73 @@ import java.util import li.cil.oc.OpenComputers import li.cil.oc.client.KeyBindings -import li.cil.oc.common.GuiType +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.inventory.ServerInventory -import li.cil.oc.util.Rarity import li.cil.oc.util.Tooltip -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumRarity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem import scala.collection.mutable +import scala.collection.convert.ImplicitConversionsToScala._ -class Server(val parent: Delegator, val tier: Int) extends traits.Delegate { - override val unlocalizedName: String = super.unlocalizedName + tier +class Server(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - override protected def tooltipName = Option(super.unlocalizedName) - - override def rarity(stack: ItemStack): EnumRarity = Rarity.byTier(tier) - - override def maxStackSize = 1 + override protected def tooltipName = Option(unlocalizedName) private object HelperInventory extends ServerInventory { var container = ItemStack.EMPTY + + override def rackSlot = -1 } - override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) { + override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[ITextComponent]) { super.tooltipExtended(stack, tooltip) if (KeyBindings.showExtendedTooltips) { HelperInventory.container = stack HelperInventory.reinitialize() val stacks = mutable.Map.empty[String, Int] - for (aStack <- (0 until HelperInventory.getSizeInventory).map(HelperInventory.getStackInSlot) if !aStack.isEmpty) { - val displayName = aStack.getDisplayName + for (aStack <- (0 until HelperInventory.getContainerSize).map(HelperInventory.getItem) if !aStack.isEmpty) { + val displayName = aStack.getHoverName.getString stacks += displayName -> (if (stacks.contains(displayName)) stacks(displayName) + 1 else 1) } if (stacks.nonEmpty) { - tooltip.addAll(Tooltip.get("server.Components")) + for (curr <- Tooltip.get("server.Components")) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } for (itemName <- stacks.keys.toArray.sorted) { - tooltip.add("- " + stacks(itemName) + "x " + itemName) + tooltip.add(new StringTextComponent("- " + stacks(itemName) + "x " + itemName).setStyle(Tooltip.DefaultStyle)) } } } } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (!player.isSneaking) { - // Open the GUI immediately on the client, too, to avoid the player - // changing the current slot before it actually opens, which can lead to - // desynchronization of the player inventory. - player.openGui(OpenComputers, GuiType.Server.id, world, 0, 0, 0) - player.swingArm(EnumHand.MAIN_HAND) + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (!player.isCrouching) { + if (!world.isClientSide) player match { + case srvPlr: ServerPlayerEntity => ContainerTypes.openServerGui(srvPlr, new ServerInventory { + override def container = stack + + override def rackSlot = -1 + + override def stillValid(player: PlayerEntity) = player == srvPlr + }, -1) + case _ => + } + player.swing(Hand.MAIN_HAND) } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } } diff --git a/src/main/scala/li/cil/oc/common/item/Tablet.scala b/src/main/scala/li/cil/oc/common/item/Tablet.scala index fd690ae722..4e4a463588 100644 --- a/src/main/scala/li/cil/oc/common/item/Tablet.scala +++ b/src/main/scala/li/cil/oc/common/item/Tablet.scala @@ -23,9 +23,11 @@ import li.cil.oc.api.network.Message import li.cil.oc.api.network.Node import li.cil.oc.{client, server} import li.cil.oc.client.KeyBindings -import li.cil.oc.common.GuiType +import li.cil.oc.client.gui import li.cil.oc.common.Slot import li.cil.oc.common.Tier +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.inventory.ComponentInventory import li.cil.oc.common.item.data.TabletData import li.cil.oc.integration.opencomputers.DriverScreen @@ -37,61 +39,74 @@ import li.cil.oc.util.Rarity import li.cil.oc.util.RotationHelper import li.cil.oc.util.Tooltip import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.block.model.ModelBakery -import net.minecraft.client.renderer.block.model.ModelResourceLocation +import net.minecraft.client.renderer.model.ModelBakery +import net.minecraft.client.renderer.model.ModelResourceLocation import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP} -import net.minecraft.item.EnumRarity +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.player.{PlayerEntity, PlayerInventory, ServerPlayerEntity} +import net.minecraft.inventory.container.INamedContainerProvider +import net.minecraft.item // Rarity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.server.integrated.IntegratedServer -import net.minecraft.util._ +import net.minecraft.util.ActionResult +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand +import net.minecraft.util.NonNullList +import net.minecraft.util.ResourceLocation +import net.minecraft.util.Util +import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.client.model.ModelLoader +import net.minecraftforge.common.extensions.IForgeItem import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.FMLCommonHandler -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ServerTickEvent -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.event.TickEvent.ClientTickEvent +import net.minecraftforge.event.TickEvent.ServerTickEvent +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fml.server.ServerLifecycleHooks -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ -class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel with traits.Chargeable { +class Tablet(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with CustomModel with traits.Chargeable { final val TimeToAnalyze = 10 - // Must be assembled to be usable so we hide it in the item list. - showInItemList = false - - override def maxStackSize = 1 - // ----------------------------------------------------------------------- // - override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = { + override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[ITextComponent]): Unit = { if (KeyBindings.showExtendedTooltips) { val info = new TabletData(stack) // Ignore/hide the screen. val components = info.items.drop(1) if (components.length > 1) { - tooltip.addAll(Tooltip.get("server.Components")) + for (curr <- Tooltip.get("server.Components")) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } components.collect { - case component if !component.isEmpty => tooltip.add("- " + component.getDisplayName) + case component if !component.isEmpty => tooltip.add(new StringTextComponent("- " + component.getHoverName.getString).setStyle(Tooltip.DefaultStyle)) } } } } - override def rarity(stack: ItemStack): EnumRarity = { + override def getRarity(stack: ItemStack): item.Rarity = { val data = new TabletData(stack) Rarity.byTier(data.tier) } override def showDurabilityBar(stack: ItemStack) = true - override def durability(stack: ItemStack): Double = { - if (stack.hasTagCompound) { + override def getDurabilityForDisplay(stack: ItemStack): Double = { + if (stack.hasTag) { val data = Tablet.Client.getWeak(stack) match { case Some(wrapper) => wrapper.data case _ => new TabletData(stack) @@ -103,7 +118,7 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) private def modelLocationFromState(running: Option[Boolean]) = { val suffix = running match { case Some(state) => if (state) "_on" else "_off" @@ -112,7 +127,7 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.ItemName.Tablet + suffix, "inventory") } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def getModelLocation(stack: ItemStack): ModelResourceLocation = { modelLocationFromState(Tablet.Client.getWeak(stack) match { case Some(tablet: TabletWrapper) => Some(tablet.data.isRunning) @@ -120,11 +135,10 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit }) } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def registerModelLocations(): Unit = { for (state <- Seq(None, Some(true), Some(false))) { - val location = modelLocationFromState(state) - ModelBakery.registerItemVariants(parent, new ResourceLocation(location.getResourceDomain + ":" + location.getResourcePath)) + ModelLoader.addSpecialModel(modelLocationFromState(state)) } } @@ -135,54 +149,56 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit val data = new TabletData(stack) traits.Chargeable.applyCharge(amount, data.energy, data.maxEnergy, used => if (!simulate) { data.energy += used - data.save(stack) + data.saveData(stack) }) } // ----------------------------------------------------------------------- // - override def update(stack: ItemStack, world: World, entity: Entity, slot: Int, selected: Boolean): Unit = + // Must be assembled to be usable so we hide it in the item list. + override def fillItemCategory(tab: ItemGroup, list: NonNullList[ItemStack]) {} + + override def inventoryTick(stack: ItemStack, world: World, entity: Entity, slot: Int, selected: Boolean): Unit = entity match { - case player: EntityPlayer => + case player: PlayerEntity => // Play an audio cue to let players know when they finished analyzing a block. - if (world.isRemote && player.getItemInUseCount == TimeToAnalyze && api.Items.get(player.getActiveItemStack) == api.Items.get(Constants.ItemName.Tablet)) { - Audio.play(player.posX.toFloat, player.posY.toFloat + 2, player.posZ.toFloat, ".") + if (world.isClientSide && player.getUseItemRemainingTicks == TimeToAnalyze && api.Items.get(player.getUseItem) == api.Items.get(Constants.ItemName.Tablet)) { + Audio.play(player.getX.toFloat, player.getY.toFloat + 2, player.getZ.toFloat, ".") } Tablet.get(stack, player).update(world, player, slot, selected) case _ => } - override def onItemUseFirst(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): EnumActionResult = { - Tablet.currentlyAnalyzing = Some((position, side, hitX, hitY, hitZ)) - super.onItemUseFirst(stack, player, position, side, hitX, hitY, hitZ) + override def onItemUseFirst(stack: ItemStack, player: PlayerEntity, world: World, pos: BlockPos, side: Direction, hitX: Float, hitY: Float, hitZ: Float, hand: Hand): ActionResultType = { + Tablet.currentlyAnalyzing = Some((BlockPosition(pos, world), side, hitX, hitY, hitZ)) + super.onItemUseFirst(stack, player, world, pos, side, hitX, hitY, hitZ, hand) } - override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - player.setActiveHand(if (player.getHeldItemMainhand == stack) EnumHand.MAIN_HAND else EnumHand.OFF_HAND) + override def onItemUse(stack: ItemStack, player: PlayerEntity, position: BlockPosition, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + player.startUsingItem(if (player.getItemInHand(Hand.MAIN_HAND) == stack) Hand.MAIN_HAND else Hand.OFF_HAND) true } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - player.setActiveHand(if (player.getHeldItemMainhand == stack) EnumHand.MAIN_HAND else EnumHand.OFF_HAND) - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + player.startUsingItem(if (player.getItemInHand(Hand.MAIN_HAND) == stack) Hand.MAIN_HAND else Hand.OFF_HAND) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } - override def getMaxItemUseDuration(stack: ItemStack): Int = 72000 + override def getUseDuration(stack: ItemStack): Int = 72000 - override def onPlayerStoppedUsing(stack: ItemStack, entity: EntityLivingBase, duration: Int): Unit = { + override def releaseUsing(stack: ItemStack, world: World, entity: LivingEntity, duration: Int): Unit = { entity match { - case player: EntityPlayer => - val world = player.getEntityWorld - val didAnalyze = getMaxItemUseDuration(stack) - duration >= TimeToAnalyze + case player: PlayerEntity => + val didAnalyze = getUseDuration(stack) - duration >= TimeToAnalyze if (didAnalyze) { - if (!world.isRemote) { + if (!world.isClientSide) { Tablet.currentlyAnalyzing match { case Some((position, side, hitX, hitY, hitZ)) => try { val computer = Tablet.get(stack, player).machine if (computer.isRunning) { - val data = new NBTTagCompound() + val data = new CompoundNBT() computer.node.sendToReachable("tablet.use", data, stack, player, position, side, Float.box(hitX), Float.box(hitY), Float.box(hitZ)) - if (!data.hasNoTags) { + if (!data.isEmpty) { computer.signal("tablet_use", data) } } @@ -195,26 +211,32 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit } } else { - if (player.isSneaking) { - if (!world.isRemote) { + if (player.isCrouching) { + if (!world.isClientSide) { val tablet = Tablet.Server.get(stack, player) tablet.machine.stop() - if (tablet.data.tier > Tier.One) { - player.openGui(OpenComputers, GuiType.TabletInner.id, world, 0, 0, 0) + if (tablet.data.tier > Tier.One) player match { + case srvPlr: ServerPlayerEntity => ContainerTypes.openTabletGui(srvPlr, Tablet.get(stack, player)) + case _ => } } } else { - if (!world.isRemote) { + if (!world.isClientSide) { val computer = Tablet.get(stack, player).machine computer.start() computer.lastError match { - case message if message != null => player.sendMessage(Localization.Analyzer.LastError(message)) + case message if message != null => player.sendMessage(Localization.Analyzer.LastError(message), Util.NIL_UUID) case _ => } } else { - player.openGui(OpenComputers, GuiType.Tablet.id, world, 0, 0, 0) + Tablet.get(stack, player).components.collect { + case Some(buffer: api.internal.TextBuffer) => buffer + }.headOption match { + case Some(buffer: api.internal.TextBuffer) => showGui(buffer) + case _ => + } } } } @@ -222,6 +244,11 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit } } + @OnlyIn(Dist.CLIENT) + private def showGui(buffer: api.internal.TextBuffer) { + Minecraft.getInstance.pushGuiLayer(new gui.Screen(buffer, true, () => true, () => buffer.isRenderingEnabled)) + } + override def maxCharge(stack: ItemStack): Double = new TabletData(stack).maxEnergy override def getCharge(stack: ItemStack): Double = new TabletData(stack).energy @@ -229,24 +256,24 @@ class Tablet(val parent: Delegator) extends traits.Delegate with CustomModel wit override def setCharge(stack: ItemStack, amount: Double): Unit = { val data = new TabletData(stack) data.energy = (0.0 max amount) min maxCharge(stack) - data.save(stack) + data.saveData(stack) } } -class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends ComponentInventory with MachineHost with internal.Tablet { +class TabletWrapper(var stack: ItemStack, var player: PlayerEntity) extends ComponentInventory with MachineHost with internal.Tablet with INamedContainerProvider { // Remember our *original* world, so we know which tablets to clear on dimension // changes of players holding tablets - since the player entity instance may be // kept the same and components are not required to properly handle world changes. - val world: World = player.world + val world: World = player.level - lazy val machine: api.machine.Machine = if (world.isRemote) null else Machine.create(this) + lazy val machine: api.machine.Machine = if (world.isClientSide) null else Machine.create(this) val data = new TabletData() - val tablet: component.Tablet = if (world.isRemote) null else new component.Tablet(this) + val tablet: component.Tablet = if (world.isClientSide) null else new component.Tablet(this) //// Client side only - private var isInitialized = !world.isRemote + private var isInitialized = !world.isClientSide var timesChanged: Int = 0 @@ -263,48 +290,45 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp def items: Array[ItemStack] = data.items - override def facing: EnumFacing = RotationHelper.fromYaw(player.rotationYaw) + override def facing: Direction = RotationHelper.fromYaw(player.yRot) - override def toLocal(value: EnumFacing): EnumFacing = - RotationHelper.toLocal(EnumFacing.NORTH, facing, value) + override def toLocal(value: Direction): Direction = + RotationHelper.toLocal(Direction.NORTH, facing, value) - override def toGlobal(value: EnumFacing): EnumFacing = - RotationHelper.toGlobal(EnumFacing.NORTH, facing, value) + override def toGlobal(value: Direction): Direction = + RotationHelper.toGlobal(Direction.NORTH, facing, value) def readFromNBT() { - if (stack.hasTagCompound) { - val data = stack.getTagCompound - load(data) - if (!world.isRemote) { - tablet.load(data.getCompoundTag(Settings.namespace + "component")) - machine.load(data.getCompoundTag(Settings.namespace + "data")) + if (stack.hasTag) { + val data = stack.getTag + loadData(data) + if (!world.isClientSide) { + tablet.loadData(data.getCompound(Settings.namespace + "component")) + machine.loadData(data.getCompound(Settings.namespace + "data")) } } } def writeToNBT(clearState: Boolean = true) { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - val data = stack.getTagCompound - if (!world.isRemote) { - if (!data.hasKey(Settings.namespace + "data")) { - data.setTag(Settings.namespace + "data", new NBTTagCompound()) + val data = stack.getOrCreateTag + if (!world.isClientSide) { + if (!data.contains(Settings.namespace + "data")) { + data.put(Settings.namespace + "data", new CompoundNBT()) } - data.setNewCompoundTag(Settings.namespace + "component", tablet.save) - data.setNewCompoundTag(Settings.namespace + "data", machine.save) + data.setNewCompoundTag(Settings.namespace + "component", tablet.saveData(_)) + data.setNewCompoundTag(Settings.namespace + "data", machine.saveData(_)) if (clearState) { // Force tablets into stopped state to avoid errors when trying to // load deleted machine states. - data.getCompoundTag(Settings.namespace + "data").removeTag("state") + data.getCompound(Settings.namespace + "data").remove("state") } } - save(data) + saveData(data) } readFromNBT() - if (!world.isRemote) { + if (!world.isClientSide) { api.Network.joinNewNetwork(machine.node) val charge = Math.max(0, this.data.energy - tablet.node.globalBuffer) tablet.node.changeBuffer(charge) @@ -313,6 +337,13 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp // ----------------------------------------------------------------------- // + override def getDisplayName = getName + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Tablet(ContainerTypes.TABLET, id, playerInventory, stack, this, containerSlotType, containerSlotTier) + + // ----------------------------------------------------------------------- // + override def onConnect(node: Node) { if (node == this.node) { connectComponents() @@ -350,9 +381,9 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp override def host: TabletWrapper = this - override def getSizeInventory: Int = items.length + override def getContainerSize: Int = items.length - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = slot == getSizeInventory - 1 && (Option(Driver.driverFor(stack, getClass)) match { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = slot == getContainerSize - 1 && (Option(Driver.driverFor(stack, getClass)) match { case Some(driver) => // Same special cases, similar as in robot, but allow keyboards, // because clip-on keyboards kinda seem to make sense, I guess. @@ -362,20 +393,20 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp case _ => false }) - override def isUsableByPlayer(player: EntityPlayer): Boolean = machine != null && machine.canInteract(player.getName) + override def stillValid(player: PlayerEntity): Boolean = machine != null && machine.canInteract(player.getName.getString) - override def markDirty(): Unit = { - data.save(stack) - player.inventory.markDirty() + override def setChanged(): Unit = { + data.saveData(stack) + player.inventory.setChanged() } // ----------------------------------------------------------------------- // - override def xPosition: Double = player.posX + override def xPosition: Double = player.getX - override def yPosition: Double = player.posY + player.getEyeHeight + override def yPosition: Double = player.getY + player.getEyeHeight - override def zPosition: Double = player.posZ + override def zPosition: Double = player.getZ override def markChanged() {} @@ -395,8 +426,8 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp case _ => Tier.None } - override def internalComponents(): Iterable[ItemStack] = (0 until getSizeInventory).collect { - case slot if !getStackInSlot(slot).isEmpty && isComponentSlot(slot, getStackInSlot(slot)) => getStackInSlot(slot) + override def internalComponents(): Iterable[ItemStack] = (0 until getContainerSize).collect { + case slot if !getItem(slot).isEmpty && isComponentSlot(slot, getItem(slot)) => getItem(slot) } override def componentSlot(address: String): Int = components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) @@ -411,7 +442,7 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp // ----------------------------------------------------------------------- // - def update(world: World, player: EntityPlayer, slot: Int, selected: Boolean) { + def update(world: World, player: PlayerEntity, slot: Int, selected: Boolean) { this.player = player if (!isInitialized) { isInitialized = true @@ -428,8 +459,8 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp client.PacketSender.sendMachineItemStateRequest(stack) } - if (!world.isRemote) { - if (isCreative && world.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (!world.isClientSide) { + if (isCreative && world.getGameTime % Settings.get.tickFrequency == 0) { machine.node.asInstanceOf[Connector].changeBuffer(Double.PositiveInfinity) } machine.update() @@ -440,10 +471,10 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp if (lastRunning != machine.isRunning) { lastRunning = machine.isRunning - markDirty() + setChanged() player match { - case mp: EntityPlayerMP => server.PacketSender.sendMachineItemState(mp, stack, machine.isRunning) + case mp: ServerPlayerEntity => server.PacketSender.sendMachineItemState(mp, stack, machine.isRunning) case _ => } @@ -459,53 +490,50 @@ class TabletWrapper(var stack: ItemStack, var player: EntityPlayer) extends Comp // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { - data.load(nbt) + override def loadData(nbt: CompoundNBT) { + data.loadData(nbt) } - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { saveComponents() - data.save(nbt) + data.saveData(nbt) } } object Tablet { // This is super-hacky, but since it's only used on the client we get away // with storing context information for analyzing a block in the singleton. - var currentlyAnalyzing: Option[(BlockPosition, EnumFacing, Float, Float, Float)] = None + var currentlyAnalyzing: Option[(BlockPosition, Direction, Float, Float, Float)] = None def getId(stack: ItemStack): String = { - - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - if (!stack.getTagCompound.hasKey(Settings.namespace + "tablet")) { - stack.getTagCompound.setString(Settings.namespace + "tablet", UUID.randomUUID().toString) + val data = stack.getOrCreateTag + if (!data.contains(Settings.namespace + "tablet")) { + data.putString(Settings.namespace + "tablet", UUID.randomUUID().toString) } - stack.getTagCompound.getString(Settings.namespace + "tablet") + data.getString(Settings.namespace + "tablet") } - def get(stack: ItemStack, holder: EntityPlayer): TabletWrapper = { - if (holder.world.isRemote) Client.get(stack, holder) + def get(stack: ItemStack, holder: PlayerEntity): TabletWrapper = { + if (holder.level.isClientSide) Client.get(stack, holder) else Server.get(stack, holder) } @SubscribeEvent def onWorldSave(e: WorldEvent.Save) { - Server.saveAll(e.getWorld) + Server.saveAll(e.getWorld.asInstanceOf[World]) } @SubscribeEvent def onWorldUnload(e: WorldEvent.Unload) { - Client.clear(e.getWorld) - Server.clear(e.getWorld) + Client.clear(e.getWorld.asInstanceOf[World]) + Server.clear(e.getWorld.asInstanceOf[World]) } @SubscribeEvent def onClientTick(e: ClientTickEvent) { Client.cleanUp() - FMLCommonHandler.instance.getMinecraftServerInstance match { - case integrated: IntegratedServer if Minecraft.getMinecraft.isGamePaused => + ServerLifecycleHooks.getCurrentServer match { + case integrated: IntegratedServer if Minecraft.getInstance.isPaused => // While the game is paused, manually keep all tablets alive, to avoid // them being cleared from the cache, causing them to stop. Client.keepAlive() @@ -531,16 +559,16 @@ object Tablet { // To allow access in cache entry init. private var currentStack: ItemStack = _ - private var currentHolder: EntityPlayer = _ + private var currentHolder: PlayerEntity = _ - def get(stack: ItemStack, holder: EntityPlayer): TabletWrapper = { + def get(stack: ItemStack, holder: PlayerEntity): TabletWrapper = { val id = getId(stack) cache.synchronized { currentStack = stack currentHolder = holder // if the item is still cached, we can detect if it is dirty (client side only) - if (holder.world.isRemote) { + if (holder.level.isClientSide) { Client.getWeak(stack) match { case Some(weak) => val timesChanged = holder.inventory.getTimesChanged @@ -559,7 +587,7 @@ object Tablet { // Force re-load on world change, in case some components store a // reference to the world object. - if (holder.world != wrapper.world) { + if (holder.level != wrapper.world) { wrapper.writeToNBT(clearState = false) wrapper.autoSave = false cache.invalidate(id) @@ -590,7 +618,7 @@ object Tablet { node.remove() } if (tablet.autoSave) tablet.writeToNBT() - tablet.markDirty() + tablet.setChanged() } } @@ -625,8 +653,8 @@ object Tablet { } def get(stack: ItemStack): Option[TabletWrapper] = { - if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "tablet")) { - val id = stack.getTagCompound.getString(Settings.namespace + "tablet") + if (stack.hasTag && stack.getTag.contains(Settings.namespace + "tablet")) { + val id = stack.getTag.getString(Settings.namespace + "tablet") cache.synchronized(Option(cache.getIfPresent(id))) } else None diff --git a/src/main/scala/li/cil/oc/common/item/TabletCase.scala b/src/main/scala/li/cil/oc/common/item/TabletCase.scala index 7ac5dcd584..62264077a8 100644 --- a/src/main/scala/li/cil/oc/common/item/TabletCase.scala +++ b/src/main/scala/li/cil/oc/common/item/TabletCase.scala @@ -1,11 +1,15 @@ package li.cil.oc.common.item +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem -class TabletCase(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class TabletCase(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier override protected def tierFromDriver(stack: ItemStack) = tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/Terminal.scala b/src/main/scala/li/cil/oc/common/item/Terminal.scala index 9f3b5410b0..07444bf7b7 100644 --- a/src/main/scala/li/cil/oc/common/item/Terminal.scala +++ b/src/main/scala/li/cil/oc/common/item/Terminal.scala @@ -2,65 +2,105 @@ package li.cil.oc.common.item import java.util +import com.google.common.base.Strings import li.cil.oc.Constants +import li.cil.oc.Localization import li.cil.oc.OpenComputers import li.cil.oc.Settings -import li.cil.oc.common.GuiType -import net.minecraft.client.renderer.block.model.ModelBakery -import net.minecraft.client.renderer.block.model.ModelResourceLocation +import li.cil.oc.api +import li.cil.oc.client.gui +import li.cil.oc.common.component +import li.cil.oc.common.tileentity.traits.TileEntity +import li.cil.oc.util.Tooltip +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.model.ModelBakery +import net.minecraft.client.renderer.model.ModelResourceLocation import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumHand +import net.minecraft.util.Hand import net.minecraft.util.ResourceLocation +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.client.model.ModelLoader +import net.minecraftforge.common.extensions.IForgeItem -class Terminal(val parent: Delegator) extends traits.Delegate with CustomModel { - override def maxStackSize = 1 +class Terminal(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with CustomModel { + def hasServer(stack: ItemStack) = stack.hasTag && stack.getTag.contains(Settings.namespace + "server") - def hasServer(stack: ItemStack) = stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "server") - - @SideOnly(Side.CLIENT) - override def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - super.tooltipLines(stack, world, tooltip, flag) + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) if (hasServer(stack)) { - val server = stack.getTagCompound.getString(Settings.namespace + "server") - tooltip.add("§8" + server.substring(0, 13) + "...§7") + val server = stack.getTag.getString(Settings.namespace + "server") + tooltip.add(new StringTextComponent("§8" + server.substring(0, 13) + "...§7")) } } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) private def modelLocationFromState(running: Boolean) = { new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.ItemName.Terminal + (if (running) "_on" else "_off"), "inventory") } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def getModelLocation(stack: ItemStack): ModelResourceLocation = { modelLocationFromState(hasServer(stack)) } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def registerModelLocations(): Unit = { for (state <- Seq(true, false)) { - val location = modelLocationFromState(state) - ModelBakery.registerItemVariants(parent, new ResourceLocation(location.getResourceDomain + ":" + location.getResourcePath)) + ModelLoader.addSpecialModel(modelLocationFromState(state)) } } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (!player.isSneaking && stack.hasTagCompound) { - val key = stack.getTagCompound.getString(Settings.namespace + "key") - val server = stack.getTagCompound.getString(Settings.namespace + "server") + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (!player.isCrouching && stack.hasTag) { + val key = stack.getTag.getString(Settings.namespace + "key") + val server = stack.getTag.getString(Settings.namespace + "server") if (key != null && !key.isEmpty && server != null && !server.isEmpty) { - if (world.isRemote) { - player.openGui(OpenComputers, GuiType.Terminal.id, world, 0, 0, 0) + if (world.isClientSide) { + if (stack.hasTag) { + val address = stack.getTag.getString(Settings.namespace + "server") + val key = stack.getTag.getString(Settings.namespace + "key") + if (!Strings.isNullOrEmpty(key) && !Strings.isNullOrEmpty(address)) { + component.TerminalServer.loaded.find(address) match { + case Some(term) if term != null && term.rack != null => term.rack match { + case rack: TileEntity with api.internal.Rack => { + def inRange = player.isAlive && !rack.isRemoved && player.distanceToSqr(rack.x + 0.5, rack.y + 0.5, rack.z + 0.5) < term.range * term.range + if (inRange) { + if (term.sidedKeys.contains(key)) showGui(stack, key, term, () => inRange) + else player.displayClientMessage(Localization.Terminal.InvalidKey, true) + } + else player.displayClientMessage(Localization.Terminal.OutOfRange, true) + } + case _ => // Eh? + } + case _ => player.displayClientMessage(Localization.Terminal.OutOfRange, true) + } + } + } } - player.swingArm(EnumHand.MAIN_HAND) + player.swing(Hand.MAIN_HAND) } } - super.onItemRightClick(stack, world, player) + super.use(stack, world, player) + } + + @OnlyIn(Dist.CLIENT) + private def showGui(stack: ItemStack, key: String, term: component.TerminalServer, inRange: () => Boolean) { + Minecraft.getInstance.pushGuiLayer(new gui.Screen(term.buffer, true, () => true, () => { + // Check if someone else bound a term to our server. + if (stack.getTag.getString(Settings.namespace + "key") != key) Minecraft.getInstance.popGuiLayer + // Check whether we're still in range. + if (!inRange()) Minecraft.getInstance.popGuiLayer + true + })) } } diff --git a/src/main/scala/li/cil/oc/common/item/TerminalServer.scala b/src/main/scala/li/cil/oc/common/item/TerminalServer.scala index 7fd58da8bd..86a4f07ab2 100644 --- a/src/main/scala/li/cil/oc/common/item/TerminalServer.scala +++ b/src/main/scala/li/cil/oc/common/item/TerminalServer.scala @@ -1,7 +1,10 @@ package li.cil.oc.common.item import li.cil.oc.Settings +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem -class TerminalServer(val parent: Delegator) extends traits.Delegate { +class TerminalServer(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { override protected def tooltipData = Seq(Settings.get.terminalsPerServer) } diff --git a/src/main/scala/li/cil/oc/common/item/TexturePicker.scala b/src/main/scala/li/cil/oc/common/item/TexturePicker.scala index fefc6e5597..936435d5b3 100644 --- a/src/main/scala/li/cil/oc/common/item/TexturePicker.scala +++ b/src/main/scala/li/cil/oc/common/item/TexturePicker.scala @@ -5,18 +5,25 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ import net.minecraft.block.Block import net.minecraft.client.Minecraft -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.Util +import net.minecraftforge.client.model.ModelDataManager +import net.minecraftforge.common.extensions.IForgeItem -class TexturePicker(val parent: Delegator) extends traits.Delegate { - override def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { - player.getEntityWorld.getBlock(position) match { +class TexturePicker(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem { + override def onItemUse(stack: ItemStack, player: PlayerEntity, position: BlockPosition, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + player.level.getBlock(position) match { case block: Block => - if (player.getEntityWorld.isRemote) { - val model = Minecraft.getMinecraft.getBlockRendererDispatcher.getModelForState(player.getEntityWorld.getBlockState(position.toBlockPos)) - if (model != null && model.getParticleTexture != null && model.getParticleTexture.getIconName != null) { - player.sendMessage(Localization.Chat.TextureName(model.getParticleTexture.getIconName)) + if (player.level.isClientSide) { + val pos = position.toBlockPos + val model = Minecraft.getInstance.getBlockRenderer.getBlockModel(player.level.getBlockState(pos)) + val particle = if (model != null) model.getParticleTexture(ModelDataManager.getModelData(player.level, pos)) else null + if (particle != null && particle.getName != null) { + player.sendMessage(Localization.Chat.TextureName(particle.getName.toString), Util.NIL_UUID) } } true diff --git a/src/main/scala/li/cil/oc/common/item/Transistor.scala b/src/main/scala/li/cil/oc/common/item/Transistor.scala index eb84cd8a60..5457754df2 100644 --- a/src/main/scala/li/cil/oc/common/item/Transistor.scala +++ b/src/main/scala/li/cil/oc/common/item/Transistor.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class Transistor(val parent: Delegator) extends traits.Delegate \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class Transistor(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeAngel.scala b/src/main/scala/li/cil/oc/common/item/UpgradeAngel.scala index ffb4e6da3a..4f65c741d8 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeAngel.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeAngel.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeAngel(val parent: Delegator) extends traits.Delegate with traits.ItemTier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeAngel(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeBattery.scala b/src/main/scala/li/cil/oc/common/item/UpgradeBattery.scala index aac2fb9b38..a5116eb79e 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeBattery.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeBattery.scala @@ -3,18 +3,22 @@ package li.cil.oc.common.item import li.cil.oc.Settings import li.cil.oc.api.driver.item.Chargeable import li.cil.oc.common.item.data.NodeData +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeBattery(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier with traits.Chargeable { - override val unlocalizedName: String = super.unlocalizedName + tier +class UpgradeBattery(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier with traits.Chargeable { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) override protected def tooltipData = Seq(Settings.get.bufferCapacitorUpgrades(tier).toInt) override def showDurabilityBar(stack: ItemStack) = true - override def durability(stack: ItemStack): Double = { + override def getDurabilityForDisplay(stack: ItemStack): Double = { val data = new NodeData(stack) 1 - data.buffer.getOrElse(0.0) / Settings.get.bufferCapacitorUpgrades(tier) } @@ -31,7 +35,7 @@ class UpgradeBattery(val parent: Delegator, val tier: Int) extends traits.Delega } traits.Chargeable.applyCharge(amount, buffer, Settings.get.bufferCapacitorUpgrades(tier), used => if (!simulate) { data.buffer = Option(buffer + used) - data.save(stack) + data.saveData(stack) }) } @@ -42,7 +46,7 @@ class UpgradeBattery(val parent: Delegator, val tier: Int) extends traits.Delega override def setCharge(stack: ItemStack, amount: Double): Unit = { val data = new NodeData(stack) data.buffer = Option((0.0 max amount) min maxCharge(stack)) - data.save(stack) + data.saveData(stack) } override def canExtract(stack: ItemStack): Boolean = true diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeChunkloader.scala b/src/main/scala/li/cil/oc/common/item/UpgradeChunkloader.scala index da2da9081c..786deef739 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeChunkloader.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeChunkloader.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeChunkloader(val parent: Delegator) extends traits.Delegate with traits.ItemTier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeChunkloader(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeContainerCard.scala b/src/main/scala/li/cil/oc/common/item/UpgradeContainerCard.scala index d2edec129a..a6eb7ee47b 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeContainerCard.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeContainerCard.scala @@ -1,9 +1,14 @@ package li.cil.oc.common.item -class UpgradeContainerCard(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem - override protected def tooltipName = Option(super.unlocalizedName) +class UpgradeContainerCard(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier + + override protected def tooltipName = Option(unlocalizedName) override protected def tooltipData = Seq(tier + 1) } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeContainerUpgrade.scala b/src/main/scala/li/cil/oc/common/item/UpgradeContainerUpgrade.scala index b118d5158b..a4e4267fa4 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeContainerUpgrade.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeContainerUpgrade.scala @@ -1,9 +1,14 @@ package li.cil.oc.common.item -class UpgradeContainerUpgrade(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem - override protected def tooltipName = Option(super.unlocalizedName) +class UpgradeContainerUpgrade(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier + + override protected def tooltipName = Option(unlocalizedName) override protected def tooltipData = Seq(tier + 1) } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeCrafting.scala b/src/main/scala/li/cil/oc/common/item/UpgradeCrafting.scala index e822f1e34c..b9f877faf7 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeCrafting.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeCrafting.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeCrafting(val parent: Delegator) extends traits.Delegate with traits.ItemTier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeCrafting(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeDatabase.scala b/src/main/scala/li/cil/oc/common/item/UpgradeDatabase.scala index dc0269aa92..20d6e404c0 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeDatabase.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeDatabase.scala @@ -2,33 +2,43 @@ package li.cil.oc.common.item import li.cil.oc.OpenComputers import li.cil.oc.Settings -import li.cil.oc.common.GuiType -import li.cil.oc.util.Rarity -import net.minecraft.entity.player.EntityPlayer +import li.cil.oc.common.container.ContainerTypes +import li.cil.oc.common.inventory.DatabaseInventory +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeDatabase(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class UpgradeDatabase(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) override protected def tooltipData = Seq(Settings.get.databaseEntriesPerTier(tier)) - override def rarity(stack: ItemStack) = Rarity.byTier(tier) + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (!player.isCrouching) { + if (!world.isClientSide) player match { + case srvPlr: ServerPlayerEntity => ContainerTypes.openDatabaseGui(srvPlr, new DatabaseInventory { + override def container = stack - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (!player.isSneaking) { - player.openGui(OpenComputers, GuiType.Database.id, world, 0, 0, 0) - player.swingArm(EnumHand.MAIN_HAND) + override def stillValid(player: PlayerEntity) = player == srvPlr + }) + case _ => + } + player.swing(Hand.MAIN_HAND) } - else if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "items")) { - stack.setTagCompound(null) - player.swingArm(EnumHand.MAIN_HAND) + else { + stack.removeTagKey(Settings.namespace + "items") + player.swing(Hand.MAIN_HAND) } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeExperience.scala b/src/main/scala/li/cil/oc/common/item/UpgradeExperience.scala index a105ea97b5..98b6e790d7 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeExperience.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeExperience.scala @@ -2,24 +2,29 @@ package li.cil.oc.common.item import java.util -import li.cil.oc.util.UpgradeExperience +import li.cil.oc.Localization +import li.cil.oc.util.Tooltip +import li.cil.oc.util.{UpgradeExperience => ExperienceUtil} import net.minecraft.client.util.ITooltipFlag +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.{Side, SideOnly} -import li.cil.oc.Localization; +import net.minecraftforge.api.distmarker.{Dist, OnlyIn} +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeExperience(val parent: Delegator) extends traits.Delegate with traits.ItemTier { - - @SideOnly(Side.CLIENT) override - def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag): Unit = { - if (stack.hasTagCompound) { +class UpgradeExperience(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) + if (stack.hasTag) { val nbt = li.cil.oc.integration.opencomputers.Item.dataTag(stack) - val experience = UpgradeExperience.getExperience(nbt) - val level = UpgradeExperience.calculateLevelFromExperience(experience) - val reportedLevel = UpgradeExperience.calculateExperienceLevel(level, experience) - tooltip.add(Localization.Tooltip.ExperienceLevel(reportedLevel)) + val experience = ExperienceUtil.getExperience(nbt) + val level = ExperienceUtil.calculateLevelFromExperience(experience) + val reportedLevel = ExperienceUtil.calculateExperienceLevel(level, experience) + tooltip.add(new StringTextComponent(Localization.Tooltip.ExperienceLevel(reportedLevel)).setStyle(Tooltip.DefaultStyle)) } - super.tooltipLines(stack, world, tooltip, flag) } } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeGenerator.scala b/src/main/scala/li/cil/oc/common/item/UpgradeGenerator.scala index 8dd2f3be4e..79be7fa62b 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeGenerator.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeGenerator.scala @@ -1,7 +1,10 @@ package li.cil.oc.common.item import li.cil.oc.Settings +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeGenerator(val parent: Delegator) extends traits.Delegate with traits.ItemTier { +class UpgradeGenerator(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { override protected def tooltipData = Seq((Settings.get.generatorEfficiency * 100).toInt) } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeHover.scala b/src/main/scala/li/cil/oc/common/item/UpgradeHover.scala index 3afd012221..ae56bdc64a 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeHover.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeHover.scala @@ -1,11 +1,15 @@ package li.cil.oc.common.item import li.cil.oc.Settings +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeHover(val parent: Delegator, val tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class UpgradeHover(props: Properties, val tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) override protected def tooltipData = Seq(Settings.get.upgradeFlightHeight(tier)) } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeInventory.scala b/src/main/scala/li/cil/oc/common/item/UpgradeInventory.scala index 5ac0ef7e8b..32026c51d6 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeInventory.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeInventory.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeInventory(val parent: Delegator) extends traits.Delegate with traits.ItemTier \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeInventory(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeInventoryController.scala b/src/main/scala/li/cil/oc/common/item/UpgradeInventoryController.scala index 773458084f..c06f369bf4 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeInventoryController.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeInventoryController.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeInventoryController(val parent: Delegator) extends traits.Delegate with traits.ItemTier \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeInventoryController(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeLeash.scala b/src/main/scala/li/cil/oc/common/item/UpgradeLeash.scala index 42f0633778..97a7cc4e03 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeLeash.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeLeash.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeLeash(val parent: Delegator) extends traits.Delegate with traits.ItemTier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeLeash(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala b/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala index be3d9fdefb..7d451b3cc8 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeMF.scala @@ -2,32 +2,39 @@ package li.cil.oc.common.item import java.util -import li.cil.oc.util.BlockPosition import li.cil.oc.Localization import li.cil.oc.Settings -import net.minecraft.entity.player.EntityPlayer +import li.cil.oc.util.BlockPosition +import li.cil.oc.util.Tooltip +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand +import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeMF(val parent: Delegator) extends traits.Delegate with traits.ItemTier { - override def onItemUseFirst(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): EnumActionResult = { - if (!player.world.isRemote && player.isSneaking) { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - val data = stack.getTagCompound - data.setIntArray(Settings.namespace + "coord", Array(position.x, position.y, position.z, player.world.provider.getDimension, side.ordinal())) - return EnumActionResult.SUCCESS +class UpgradeMF(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + override def onItemUseFirst(stack: ItemStack, player: PlayerEntity, world: World, pos: BlockPos, side: Direction, hitX: Float, hitY: Float, hitZ: Float, hand: Hand): ActionResultType = { + if (!player.level.isClientSide && player.isCrouching) { + val data = stack.getOrCreateTag + data.putString(Settings.namespace + "dimension", world.dimension.location.toString) + data.putIntArray(Settings.namespace + "coord", Array(pos.getX, pos.getY, pos.getZ, side.ordinal())) + return ActionResultType.sidedSuccess(player.level.isClientSide) } - super.onItemUseFirst(stack, player, position, side, hitX, hitY, hitZ) + super.onItemUseFirst(stack, player, world, pos, side, hitX, hitY, hitZ, hand) } - override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) { - tooltip.add(Localization.Tooltip.MFULinked(stack.getTagCompound match { - case data: NBTTagCompound => data.hasKey(Settings.namespace + "coord") + override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[ITextComponent]) { + tooltip.add(new StringTextComponent(Localization.Tooltip.MFULinked(stack.getTag match { + case data: CompoundNBT => data.contains(Settings.namespace + "coord") case _ => false - })) + })).setStyle(Tooltip.DefaultStyle)) } } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeNavigation.scala b/src/main/scala/li/cil/oc/common/item/UpgradeNavigation.scala index 0c8ac4870c..d2e847e767 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeNavigation.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeNavigation.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeNavigation(val parent: Delegator) extends traits.Delegate with traits.ItemTier \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeNavigation(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/UpgradePiston.scala b/src/main/scala/li/cil/oc/common/item/UpgradePiston.scala index 83f6f7cf3d..e8dff7e8fa 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradePiston.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradePiston.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradePiston(val parent: Delegator) extends traits.Delegate with traits.ItemTier \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradePiston(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeSign.scala b/src/main/scala/li/cil/oc/common/item/UpgradeSign.scala index 56fa772c56..7ca4cb9635 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeSign.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeSign.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeSign(val parent: Delegator) extends traits.Delegate with traits.ItemTier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeSign(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeSolarGenerator.scala b/src/main/scala/li/cil/oc/common/item/UpgradeSolarGenerator.scala index f0487450f0..f04fb24726 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeSolarGenerator.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeSolarGenerator.scala @@ -1,7 +1,10 @@ package li.cil.oc.common.item import li.cil.oc.Settings +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeSolarGenerator(val parent: Delegator) extends traits.Delegate with traits.ItemTier { +class UpgradeSolarGenerator(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { override protected def tooltipData = Seq((Settings.get.solarGeneratorEfficiency * 100).toInt) } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeStickyPiston.scala b/src/main/scala/li/cil/oc/common/item/UpgradeStickyPiston.scala index befd47bc16..fbfaeb5cec 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeStickyPiston.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeStickyPiston.scala @@ -1,6 +1,10 @@ package li.cil.oc.common.item -class UpgradeStickyPiston(val parent: Delegator) extends traits.Delegate with traits.ItemTier { - override protected def tooltipName: Option[String] = Option(super.unlocalizedName) +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeStickyPiston(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + override protected def tooltipName: Option[String] = Option(unlocalizedName) } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeTank.scala b/src/main/scala/li/cil/oc/common/item/UpgradeTank.scala index 00506d0945..7945cbd4b5 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeTank.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeTank.scala @@ -3,24 +3,29 @@ package li.cil.oc.common.item import java.util import li.cil.oc.Settings +import li.cil.oc.util.Tooltip import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.common.extensions.IForgeItem -class UpgradeTank(val parent: Delegator) extends traits.Delegate with traits.ItemTier { - @SideOnly(Side.CLIENT) override - def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag): Unit = { - if (stack.hasTagCompound) { - FluidStack.loadFluidStackFromNBT(stack.getTagCompound.getCompoundTag(Settings.namespace + "data")) match { +class UpgradeTank(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) + if (stack.hasTag) { + FluidStack.loadFluidStackFromNBT(stack.getTag.getCompound(Settings.namespace + "data")) match { case stack: FluidStack => - tooltip.add(stack.getFluid.getLocalizedName(stack) + ": " + stack.amount + "/16000") + tooltip.add(new StringTextComponent(stack.getFluid.getAttributes.getDisplayName(stack).getString + ": " + stack.getAmount + "/16000").setStyle(Tooltip.DefaultStyle)) case _ => } } - super.tooltipLines(stack, world, tooltip, flag) } } diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeTankController.scala b/src/main/scala/li/cil/oc/common/item/UpgradeTankController.scala index ff0d347341..7968768509 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeTankController.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeTankController.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeTankController(val parent: Delegator) extends traits.Delegate with traits.ItemTier \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeTankController(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeTractorBeam.scala b/src/main/scala/li/cil/oc/common/item/UpgradeTractorBeam.scala index e9dba02c85..eec70e8dfe 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeTractorBeam.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeTractorBeam.scala @@ -1,3 +1,7 @@ package li.cil.oc.common.item -class UpgradeTractorBeam(val parent: Delegator) extends traits.Delegate with traits.ItemTier \ No newline at end of file +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeTractorBeam(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/item/UpgradeTrading.scala b/src/main/scala/li/cil/oc/common/item/UpgradeTrading.scala index 30806741d2..7762236a61 100644 --- a/src/main/scala/li/cil/oc/common/item/UpgradeTrading.scala +++ b/src/main/scala/li/cil/oc/common/item/UpgradeTrading.scala @@ -1,5 +1,9 @@ package li.cil.oc.common.item -class UpgradeTrading(val parent: Delegator) extends traits.Delegate with traits.ItemTier { - override protected def tooltipName: Option[String] = Option(super.unlocalizedName) +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem + +class UpgradeTrading(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + override protected def tooltipName: Option[String] = Option(unlocalizedName) } diff --git a/src/main/scala/li/cil/oc/common/item/WirelessNetworkCard.scala b/src/main/scala/li/cil/oc/common/item/WirelessNetworkCard.scala index 6356d87711..acbed73313 100644 --- a/src/main/scala/li/cil/oc/common/item/WirelessNetworkCard.scala +++ b/src/main/scala/li/cil/oc/common/item/WirelessNetworkCard.scala @@ -1,9 +1,12 @@ package li.cil.oc.common.item -import li.cil.oc.common.Tier +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties +import net.minecraftforge.common.extensions.IForgeItem -class WirelessNetworkCard(val parent: Delegator, var tier: Int) extends traits.Delegate with traits.ItemTier { - override val unlocalizedName = super.unlocalizedName + tier +class WirelessNetworkCard(props: Properties, var tier: Int) extends Item(props) with IForgeItem with traits.SimpleItem with traits.ItemTier { + @Deprecated + override def getDescriptionId = super.getDescriptionId + tier - override protected def tooltipName = Option(super.unlocalizedName) + override protected def tooltipName = Option(unlocalizedName) } diff --git a/src/main/scala/li/cil/oc/common/item/Wrench.scala b/src/main/scala/li/cil/oc/common/item/Wrench.scala index d2741a32e8..9820d28a50 100644 --- a/src/main/scala/li/cil/oc/common/item/Wrench.scala +++ b/src/main/scala/li/cil/oc/common/item/Wrench.scala @@ -1,45 +1,48 @@ package li.cil.oc.common.item import li.cil.oc.api -import li.cil.oc.common.asm.Injectable -import li.cil.oc.integration.Mods +import li.cil.oc.common.block.SimpleBlock import net.minecraft.block.Block -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.init.Blocks +import net.minecraft.block.Blocks +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand +import net.minecraft.util.Rotation import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IWorldReader import net.minecraft.world.World +import net.minecraftforge.common.extensions.IForgeItem -@Injectable.InterfaceList(Array( - new Injectable.Interface(value = "ic2.api.item.IBoxable", modid = Mods.IDs.IndustrialCraft2) -)) -class Wrench extends traits.SimpleItem with api.internal.Wrench { - setHarvestLevel("wrench", 1) - setMaxStackSize(1) +class Wrench(props: Properties) extends Item(props) with IForgeItem with traits.SimpleItem with api.internal.Wrench { + override def doesSneakBypassUse(stack: ItemStack, world: IWorldReader, pos: BlockPos, player: PlayerEntity): Boolean = true - override def doesSneakBypassUse(stack: ItemStack, world: IBlockAccess, pos: BlockPos, player: EntityPlayer): Boolean = true - - override def onItemUseFirst(player: EntityPlayer, world: World, pos: BlockPos, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float, hand: EnumHand): EnumActionResult = { - if (world.isBlockLoaded(pos) && world.isBlockModifiable(player, pos)) world.getBlockState(pos).getBlock match { - case block: Block if block.rotateBlock(world, pos, side) => - block.neighborChanged(world.getBlockState(pos), world, pos, Blocks.AIR, pos) - player.swingArm(hand) - if (!world.isRemote) EnumActionResult.SUCCESS else EnumActionResult.PASS - case _ => - super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand) + override def onItemUseFirst(stack: ItemStack, player: PlayerEntity, world: World, pos: BlockPos, side: Direction, hitX: Float, hitY: Float, hitZ: Float, hand: Hand): ActionResultType = { + if (world.isLoaded(pos) && world.mayInteract(player, pos)) { + val state = world.getBlockState(pos) + state.getBlock match { + case block: SimpleBlock if block.rotateBlock(world, pos, side) => + state.neighborChanged(world, pos, Blocks.AIR, pos, false) + player.swing(hand) + if (!world.isClientSide) ActionResultType.sidedSuccess(world.isClientSide) else ActionResultType.PASS + case _ => + val updated = state.rotate(world, pos, Rotation.CLOCKWISE_90) + if (updated != state) { + world.setBlock(pos, updated, 3) + player.swing(hand) + if (!world.isClientSide) ActionResultType.sidedSuccess(world.isClientSide) else ActionResultType.PASS + } + else super.onItemUseFirst(stack, player, world, pos, side, hitX, hitY, hitZ, hand) + } } - else super.onItemUseFirst(player, world, pos, side, hitX, hitY, hitZ, hand) + else super.onItemUseFirst(stack, player, world, pos, side, hitX, hitY, hitZ, hand) } - def useWrenchOnBlock(player: EntityPlayer, world: World, pos: BlockPos, simulate: Boolean): Boolean = { - if (!simulate) player.swingArm(EnumHand.MAIN_HAND) + def useWrenchOnBlock(player: PlayerEntity, world: World, pos: BlockPos, simulate: Boolean): Boolean = { + if (!simulate) player.swing(Hand.MAIN_HAND) true } - - // IndustrialCraft 2 - def canBeStoredInToolbox(stack: ItemStack): Boolean = true } diff --git a/src/main/scala/li/cil/oc/common/item/data/DebugCardData.scala b/src/main/scala/li/cil/oc/common/item/data/DebugCardData.scala index b27ef3925a..6673fe12b6 100644 --- a/src/main/scala/li/cil/oc/common/item/data/DebugCardData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/DebugCardData.scala @@ -1,35 +1,35 @@ package li.cil.oc.common.item.data -import li.cil.oc.server.component.DebugCard.AccessContext import li.cil.oc.Constants import li.cil.oc.Settings +import li.cil.oc.server.component.DebugCard.AccessContext import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT class DebugCardData extends ItemData(Constants.ItemName.DebugCard) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var access: Option[AccessContext] = None private final val DataTag = Settings.namespace + "data" - override def load(nbt: NBTTagCompound): Unit = { - access = AccessContext.load(dataTag(nbt)) + override def loadData(nbt: CompoundNBT): Unit = { + access = AccessContext.loadData(dataTag(nbt)) } - override def save(nbt: NBTTagCompound): Unit = { + override def saveData(nbt: CompoundNBT): Unit = { val tag = dataTag(nbt) AccessContext.remove(tag) - access.foreach(_.save(tag)) + access.foreach(_.saveData(tag)) } - private def dataTag(nbt: NBTTagCompound) = { - if (!nbt.hasKey(DataTag)) { - nbt.setTag(DataTag, new NBTTagCompound()) + private def dataTag(nbt: CompoundNBT) = { + if (!nbt.contains(DataTag)) { + nbt.put(DataTag, new CompoundNBT()) } - nbt.getCompoundTag(DataTag) + nbt.getCompound(DataTag) } } diff --git a/src/main/scala/li/cil/oc/common/item/data/DriveData.scala b/src/main/scala/li/cil/oc/common/item/data/DriveData.scala index 0e4b81fffa..52190f9f20 100644 --- a/src/main/scala/li/cil/oc/common/item/data/DriveData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/DriveData.scala @@ -2,14 +2,14 @@ package li.cil.oc.common.item.data import li.cil.oc.Settings import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import li.cil.oc.server.fs -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity class DriveData extends ItemData(null) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var isUnmanaged = false @@ -22,29 +22,29 @@ class DriveData extends ItemData(null) { private final val UnmanagedTag = Settings.namespace + "unmanaged" private val LockTag = Settings.namespace + "lock" - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { isUnmanaged = nbt.getBoolean(UnmanagedTag) - lockInfo = if (nbt.hasKey(LockTag)) { + lockInfo = if (nbt.contains(LockTag)) { nbt.getString(LockTag) } else "" } - override def save(nbt: NBTTagCompound) { - nbt.setBoolean(UnmanagedTag, isUnmanaged) - nbt.setString(LockTag, lockInfo) + override def saveData(nbt: CompoundNBT) { + nbt.putBoolean(UnmanagedTag, isUnmanaged) + nbt.putString(LockTag, lockInfo) } } object DriveData { - def lock(stack: ItemStack, player: EntityPlayer): Unit = { - val key = player.getName + def lock(stack: ItemStack, player: PlayerEntity): Unit = { + val key = player.getName.getString val data = new DriveData(stack) if (!data.isLocked) { data.lockInfo = key match { case name: String if name != null && name.nonEmpty => name case _ => "notch" // meaning: "unknown" } - data.save(stack) + data.saveData(stack) } } @@ -55,6 +55,6 @@ object DriveData { data.lockInfo = "" } data.isUnmanaged = unmanaged - data.save(stack) + data.saveData(stack) } } diff --git a/src/main/scala/li/cil/oc/common/item/data/DroneData.scala b/src/main/scala/li/cil/oc/common/item/data/DroneData.scala index ac7e2f6fc0..481a998c28 100644 --- a/src/main/scala/li/cil/oc/common/item/data/DroneData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/DroneData.scala @@ -4,26 +4,26 @@ import com.google.common.base.Strings import li.cil.oc.Constants import li.cil.oc.util.ItemUtils import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT class DroneData extends MicrocontrollerData(Constants.ItemName.Drone) { def this(stack: ItemStack) = { this() - load(stack) + loadData(stack) } var name = "" - override def load(nbt: NBTTagCompound): Unit = { - super.load(nbt) + override def loadData(nbt: CompoundNBT): Unit = { + super.loadData(nbt) name = ItemUtils.getDisplayName(nbt).getOrElse("") if (Strings.isNullOrEmpty(name)) { name = RobotData.randomName } } - override def save(nbt: NBTTagCompound): Unit = { - super.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = { + super.saveData(nbt) if (!Strings.isNullOrEmpty(name)) { ItemUtils.setDisplayName(nbt, name) } diff --git a/src/main/scala/li/cil/oc/common/item/data/HoverBootsData.scala b/src/main/scala/li/cil/oc/common/item/data/HoverBootsData.scala index b092b8e8aa..9b0b70a0ba 100644 --- a/src/main/scala/li/cil/oc/common/item/data/HoverBootsData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/HoverBootsData.scala @@ -3,23 +3,23 @@ package li.cil.oc.common.item.data import li.cil.oc.Constants import li.cil.oc.Settings import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT class HoverBootsData extends ItemData(Constants.ItemName.HoverBoots) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var charge = 0.0 private final val ChargeTag = Settings.namespace + "charge" - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { charge = nbt.getDouble(ChargeTag) } - override def save(nbt: NBTTagCompound) { - nbt.setDouble(ChargeTag, charge) + override def saveData(nbt: CompoundNBT) { + nbt.putDouble(ChargeTag, charge) } } diff --git a/src/main/scala/li/cil/oc/common/item/data/ItemData.scala b/src/main/scala/li/cil/oc/common/item/data/ItemData.scala index 4fa2a58f56..82e7d5ef73 100644 --- a/src/main/scala/li/cil/oc/common/item/data/ItemData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/ItemData.scala @@ -3,29 +3,26 @@ package li.cil.oc.common.item.data import li.cil.oc.api import li.cil.oc.api.Persistable import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT abstract class ItemData(val itemName: String) extends Persistable { - def load(stack: ItemStack) { - if (stack.hasTagCompound) { + def loadData(stack: ItemStack) { + if (stack.hasTag) { // Because ItemStack's load function doesn't copy the compound tag, // but keeps it as is, leading to oh so fun bugs! - load(stack.getTagCompound.copy().asInstanceOf[NBTTagCompound]) + loadData(stack.getTag.copy().asInstanceOf[CompoundNBT]) } } - def save(stack: ItemStack) { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - save(stack.getTagCompound) + def saveData(stack: ItemStack) { + saveData(stack.getOrCreateTag) } def createItemStack() = { if (itemName == null) ItemStack.EMPTY else { val stack = api.Items.get(itemName).createItemStack(1) - save(stack) + saveData(stack) stack } } diff --git a/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala b/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala index 9d1f470365..33ec629e93 100644 --- a/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/MicrocontrollerData.scala @@ -6,13 +6,13 @@ import li.cil.oc.api import li.cil.oc.common.Tier import li.cil.oc.util.ExtendedNBT._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraftforge.common.util.Constants.NBT class MicrocontrollerData(itemName: String = Constants.BlockName.Microcontroller) extends ItemData(itemName) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var tier = Tier.One @@ -25,11 +25,11 @@ class MicrocontrollerData(itemName: String = Constants.BlockName.Microcontroller private final val ComponentsTag = Settings.namespace + "components" private final val StoredEnergyTag = Settings.namespace + "storedEnergy" - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { tier = nbt.getByte(TierTag) - components = nbt.getTagList(ComponentsTag, NBT.TAG_COMPOUND). - toArray[NBTTagCompound].map(new ItemStack(_)).filter(!_.isEmpty) - storedEnergy = nbt.getInteger(StoredEnergyTag) + components = nbt.getList(ComponentsTag, NBT.TAG_COMPOUND). + toTagArray[CompoundNBT].map(ItemStack.of(_)).filter(!_.isEmpty) + storedEnergy = nbt.getInt(StoredEnergyTag) // Reserve slot for EEPROM if necessary, avoids having to resize the // components array in the MCU tile entity, which isn't possible currently. @@ -38,16 +38,16 @@ class MicrocontrollerData(itemName: String = Constants.BlockName.Microcontroller } } - override def save(nbt: NBTTagCompound) { - nbt.setByte(TierTag, tier.toByte) + override def saveData(nbt: CompoundNBT) { + nbt.putByte(TierTag, tier.toByte) nbt.setNewTagList(ComponentsTag, components.filter(!_.isEmpty).toIterable) - nbt.setInteger(StoredEnergyTag, storedEnergy) + nbt.putInt(StoredEnergyTag, storedEnergy) } def copyItemStack(): ItemStack = { val stack = createItemStack() val newInfo = new MicrocontrollerData(stack) - newInfo.save(stack) + newInfo.saveData(stack) stack } } diff --git a/src/main/scala/li/cil/oc/common/item/data/NanomachineData.scala b/src/main/scala/li/cil/oc/common/item/data/NanomachineData.scala index 949786d0db..e17463505d 100644 --- a/src/main/scala/li/cil/oc/common/item/data/NanomachineData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/NanomachineData.scala @@ -4,40 +4,40 @@ import li.cil.oc.common.nanomachines.ControllerImpl import li.cil.oc.Constants import li.cil.oc.Settings import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT class NanomachineData extends ItemData(Constants.ItemName.Nanomachines) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } def this(controller: ControllerImpl) { this() uuid = controller.uuid - val nbt = new NBTTagCompound() - controller.configuration.save(nbt, forItem = true) + val nbt = new CompoundNBT() + controller.configuration.saveData(nbt, forItem = true) configuration = Option(nbt) } var uuid = "" - var configuration: Option[NBTTagCompound] = None + var configuration: Option[CompoundNBT] = None private final val UUIDTag = Settings.namespace + "uuid" private final val ConfigurationTag = Settings.namespace + "configuration" - override def load(nbt: NBTTagCompound): Unit = { + override def loadData(nbt: CompoundNBT): Unit = { uuid = nbt.getString(UUIDTag) - if (nbt.hasKey(ConfigurationTag)) { - configuration = Option(nbt.getCompoundTag(ConfigurationTag)) + if (nbt.contains(ConfigurationTag)) { + configuration = Option(nbt.getCompound(ConfigurationTag)) } else { configuration = None } } - override def save(nbt: NBTTagCompound): Unit = { - nbt.setString(UUIDTag, uuid) - configuration.foreach(nbt.setTag(ConfigurationTag, _)) + override def saveData(nbt: CompoundNBT): Unit = { + nbt.putString(UUIDTag, uuid) + configuration.foreach(nbt.put(ConfigurationTag, _)) } } diff --git a/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala b/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala index 2d2cd36245..be8c95af20 100644 --- a/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/NavigationUpgradeData.scala @@ -3,20 +3,20 @@ package li.cil.oc.common.item.data import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.item.ItemMap +import net.minecraft.item.FilledMapItem import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.world.World class NavigationUpgradeData extends ItemData(Constants.ItemName.NavigationUpgrade) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } - var map = new ItemStack(net.minecraft.init.Items.FILLED_MAP) + var map = new ItemStack(net.minecraft.item.Items.FILLED_MAP) - def mapData(world: World) = try map.getItem.asInstanceOf[ItemMap].getMapData(map, world) catch { + def mapData(world: World) = try FilledMapItem.getSavedData(map, world) catch { case _: Throwable => throw new Exception("invalid map") } @@ -28,28 +28,25 @@ class NavigationUpgradeData extends ItemData(Constants.ItemName.NavigationUpgrad private final val DataTag = Settings.namespace + "data" private final val MapTag = Settings.namespace + "map" - override def load(stack: ItemStack) { - if (stack.hasTagCompound) { - load(stack.getTagCompound.getCompoundTag(DataTag)) + override def loadData(stack: ItemStack) { + if (stack.hasTag) { + loadData(stack.getTag.getCompound(DataTag)) } } - override def save(stack: ItemStack) { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - save(stack.getCompoundTag(DataTag)) + override def saveData(stack: ItemStack) { + saveData(stack.getOrCreateTagElement(DataTag)) } - override def load(nbt: NBTTagCompound) { - if (nbt.hasKey(MapTag)) { - map = new ItemStack(nbt.getCompoundTag(MapTag)) + override def loadData(nbt: CompoundNBT) { + if (nbt.contains(MapTag)) { + map = ItemStack.of(nbt.getCompound(MapTag)) } } - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { if (map != null) { - nbt.setNewCompoundTag(MapTag, map.writeToNBT) + nbt.setNewCompoundTag(MapTag, map.save) } } } diff --git a/src/main/scala/li/cil/oc/common/item/data/NodeData.scala b/src/main/scala/li/cil/oc/common/item/data/NodeData.scala index 472eeba24c..ca7a44d3ad 100644 --- a/src/main/scala/li/cil/oc/common/item/data/NodeData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/NodeData.scala @@ -3,13 +3,13 @@ package li.cil.oc.common.item.data import li.cil.oc.Settings import li.cil.oc.api.network.Visibility import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT // Generic one for items that are used as components; gets the items node info. class NodeData extends ItemData(null) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var address: Option[String] = None @@ -18,31 +18,31 @@ class NodeData extends ItemData(null) { private final val DataTag = Settings.namespace + "data" - override def load(nbt: NBTTagCompound): Unit = { - val nodeNbt = nbt.getCompoundTag(DataTag).getCompoundTag(NodeData.NodeTag) - if (nodeNbt.hasKey(NodeData.AddressTag)) { + override def loadData(nbt: CompoundNBT): Unit = { + val nodeNbt = nbt.getCompound(DataTag).getCompound(NodeData.NodeTag) + if (nodeNbt.contains(NodeData.AddressTag)) { address = Option(nodeNbt.getString(NodeData.AddressTag)) } - if (nodeNbt.hasKey(NodeData.BufferTag)) { + if (nodeNbt.contains(NodeData.BufferTag)) { buffer = Option(nodeNbt.getDouble(NodeData.BufferTag)) } - if (nodeNbt.hasKey(NodeData.VisibilityTag)) { - visibility = Option(Visibility.values()(nodeNbt.getInteger(NodeData.VisibilityTag))) + if (nodeNbt.contains(NodeData.VisibilityTag)) { + visibility = Option(Visibility.values()(nodeNbt.getInt(NodeData.VisibilityTag))) } } - override def save(nbt: NBTTagCompound): Unit = { - if (!nbt.hasKey(DataTag)) { - nbt.setTag(DataTag, new NBTTagCompound()) + override def saveData(nbt: CompoundNBT): Unit = { + if (!nbt.contains(DataTag)) { + nbt.put(DataTag, new CompoundNBT()) } - val dataNbt = nbt.getCompoundTag(DataTag) - if (!dataNbt.hasKey(NodeData.NodeTag)) { - dataNbt.setTag(NodeData.NodeTag, new NBTTagCompound()) + val dataNbt = nbt.getCompound(DataTag) + if (!dataNbt.contains(NodeData.NodeTag)) { + dataNbt.put(NodeData.NodeTag, new CompoundNBT()) } - val nodeNbt = dataNbt.getCompoundTag(NodeData.NodeTag) - address.foreach(nodeNbt.setString(NodeData.AddressTag, _)) - buffer.foreach(nodeNbt.setDouble(NodeData.BufferTag, _)) - visibility.map(_.ordinal()).foreach(nodeNbt.setInteger(NodeData.VisibilityTag, _)) + val nodeNbt = dataNbt.getCompound(NodeData.NodeTag) + address.foreach(nodeNbt.putString(NodeData.AddressTag, _)) + buffer.foreach(nodeNbt.putDouble(NodeData.BufferTag, _)) + visibility.map(_.ordinal()).foreach(nodeNbt.putInt(NodeData.VisibilityTag, _)) } } diff --git a/src/main/scala/li/cil/oc/common/item/data/PrintData.scala b/src/main/scala/li/cil/oc/common/item/data/PrintData.scala index 3f1ac731ea..9644d0edd6 100644 --- a/src/main/scala/li/cil/oc/common/item/data/PrintData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/PrintData.scala @@ -9,7 +9,7 @@ import li.cil.oc.common.IMC import li.cil.oc.util.ExtendedAABB._ import li.cil.oc.util.ExtendedNBT._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.util.math.AxisAlignedBB import net.minecraftforge.common.util.Constants.NBT @@ -18,7 +18,7 @@ import scala.collection.mutable class PrintData extends ItemData(Constants.BlockName.Print) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var label: Option[String] = None @@ -72,17 +72,17 @@ class PrintData extends ItemData(Constants.BlockName.Print) { private final val NoclipOffTag = "noclipOff" private final val NoclipOnTag = "noclipOn" - override def load(nbt: NBTTagCompound): Unit = { - if (nbt.hasKey(LabelTag)) label = Option(nbt.getString(LabelTag)) else label = None - if (nbt.hasKey(TooltipTag)) tooltip = Option(nbt.getString(TooltipTag)) else tooltip = None + override def loadData(nbt: CompoundNBT): Unit = { + if (nbt.contains(LabelTag)) label = Option(nbt.getString(LabelTag)) else label = None + if (nbt.contains(TooltipTag)) tooltip = Option(nbt.getString(TooltipTag)) else tooltip = None isButtonMode = nbt.getBoolean(IsButtonModeTag) - redstoneLevel = nbt.getInteger(RedstoneLevelTag) max 0 min 15 + redstoneLevel = nbt.getInt(RedstoneLevelTag) max 0 min 15 if (nbt.getBoolean(RedstoneLevelTagCompat)) redstoneLevel = 15 pressurePlate = nbt.getBoolean(PressurePlateTag) stateOff.clear() - stateOff ++= nbt.getTagList(StateOffTag, NBT.TAG_COMPOUND).map(PrintData.nbtToShape) + stateOff ++= nbt.getList(StateOffTag, NBT.TAG_COMPOUND).map(PrintData.nbtToShape) stateOn.clear() - stateOn ++= nbt.getTagList(StateOnTag, NBT.TAG_COMPOUND).map(PrintData.nbtToShape) + stateOn ++= nbt.getList(StateOnTag, NBT.TAG_COMPOUND).map(PrintData.nbtToShape) isBeaconBase = nbt.getBoolean(IsBeaconBaseTag) lightLevel = (nbt.getByte(LightLevelTag) & 0xFF) max 0 min 15 noclipOff = nbt.getBoolean(NoclipOffTag) @@ -91,18 +91,18 @@ class PrintData extends ItemData(Constants.BlockName.Print) { opacityDirty = true } - override def save(nbt: NBTTagCompound): Unit = { - label.foreach(nbt.setString(LabelTag, _)) - tooltip.foreach(nbt.setString(TooltipTag, _)) - nbt.setBoolean(IsButtonModeTag, isButtonMode) - nbt.setInteger(RedstoneLevelTag, redstoneLevel) - nbt.setBoolean(PressurePlateTag, pressurePlate) + override def saveData(nbt: CompoundNBT): Unit = { + label.foreach(nbt.putString(LabelTag, _)) + tooltip.foreach(nbt.putString(TooltipTag, _)) + nbt.putBoolean(IsButtonModeTag, isButtonMode) + nbt.putInt(RedstoneLevelTag, redstoneLevel) + nbt.putBoolean(PressurePlateTag, pressurePlate) nbt.setNewTagList(StateOffTag, stateOff.map(PrintData.shapeToNBT)) nbt.setNewTagList(StateOnTag, stateOn.map(PrintData.shapeToNBT)) - nbt.setBoolean(IsBeaconBaseTag, isBeaconBase) - nbt.setByte(LightLevelTag, lightLevel.toByte) - nbt.setBoolean(NoclipOffTag, noclipOff) - nbt.setBoolean(NoclipOnTag, noclipOn) + nbt.putBoolean(IsBeaconBaseTag, isBeaconBase) + nbt.putByte(LightLevelTag, lightLevel.toByte) + nbt.putBoolean(NoclipOffTag, noclipOff) + nbt.putBoolean(NoclipOnTag, noclipOn) } } @@ -179,9 +179,9 @@ object PrintData { 0 } - def nbtToShape(nbt: NBTTagCompound): Shape = { + def nbtToShape(nbt: CompoundNBT): Shape = { val aabb = - if (nbt.hasKey("minX")) { + if (nbt.contains("minX")) { // Compatibility with shapes created with earlier dev-builds. val minX = nbt.getByte("minX") / 16f val minY = nbt.getByte("minY") / 16f @@ -202,13 +202,13 @@ object PrintData { new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ) } val texture = nbt.getString("texture") - val tint = if (nbt.hasKey("tint")) Option(nbt.getInteger("tint")) else None + val tint = if (nbt.contains("tint")) Option(nbt.getInt("tint")) else None new Shape(aabb, texture, tint) } - def shapeToNBT(shape: Shape): NBTTagCompound = { - val nbt = new NBTTagCompound() - nbt.setByteArray("bounds", Array( + def shapeToNBT(shape: Shape): CompoundNBT = { + val nbt = new CompoundNBT() + nbt.putByteArray("bounds", Array( (shape.bounds.minX * 16).round.toByte, (shape.bounds.minY * 16).round.toByte, (shape.bounds.minZ * 16).round.toByte, @@ -216,8 +216,8 @@ object PrintData { (shape.bounds.maxY * 16).round.toByte, (shape.bounds.maxZ * 16).round.toByte )) - nbt.setString("texture", shape.texture) - shape.tint.foreach(nbt.setInteger("tint", _)) + nbt.putString("texture", shape.texture) + shape.tint.foreach(nbt.putInt("tint", _)) nbt } diff --git a/src/main/scala/li/cil/oc/common/item/data/RaidData.scala b/src/main/scala/li/cil/oc/common/item/data/RaidData.scala index 1b6b045d75..19f5191579 100644 --- a/src/main/scala/li/cil/oc/common/item/data/RaidData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/RaidData.scala @@ -4,18 +4,18 @@ import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.util.ExtendedNBT._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraftforge.common.util.Constants.NBT class RaidData extends ItemData(Constants.BlockName.Raid) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var disks = Array.empty[ItemStack] - var filesystem = new NBTTagCompound() + var filesystem = new CompoundNBT() var label: Option[String] = None @@ -23,18 +23,18 @@ class RaidData extends ItemData(Constants.BlockName.Raid) { private final val FileSystemTag = Settings.namespace + "filesystem" private final val LabelTag = Settings.namespace + "label" - override def load(nbt: NBTTagCompound): Unit = { - disks = nbt.getTagList(DisksTag, NBT.TAG_COMPOUND). - toArray[NBTTagCompound].map(new ItemStack(_)) - filesystem = nbt.getCompoundTag(FileSystemTag) - if (nbt.hasKey(LabelTag)) { + override def loadData(nbt: CompoundNBT): Unit = { + disks = nbt.getList(DisksTag, NBT.TAG_COMPOUND). + toTagArray[CompoundNBT].map(ItemStack.of(_)) + filesystem = nbt.getCompound(FileSystemTag) + if (nbt.contains(LabelTag)) { label = Option(nbt.getString(LabelTag)) } } - override def save(nbt: NBTTagCompound): Unit = { + override def saveData(nbt: CompoundNBT): Unit = { nbt.setNewTagList(DisksTag, disks.toIterable) - nbt.setTag(FileSystemTag, filesystem) - label.foreach(nbt.setString(LabelTag, _)) + nbt.put(FileSystemTag, filesystem) + label.foreach(nbt.putString(LabelTag, _)) } } diff --git a/src/main/scala/li/cil/oc/common/item/data/RobotData.scala b/src/main/scala/li/cil/oc/common/item/data/RobotData.scala index 3cafcc9452..4e339295e7 100644 --- a/src/main/scala/li/cil/oc/common/item/data/RobotData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/RobotData.scala @@ -10,7 +10,7 @@ import li.cil.oc.integration.opencomputers.DriverScreen import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ItemUtils import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraftforge.common.util.Constants.NBT import scala.io.Source @@ -33,7 +33,7 @@ object RobotData { class RobotData extends ItemData(Constants.BlockName.Robot) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var name = "" @@ -59,33 +59,33 @@ class RobotData extends ItemData(Constants.BlockName.Robot) { private final val ContainersTag = Settings.namespace + "containers" private final val LightColorTag = Settings.namespace + "lightColor" - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { name = ItemUtils.getDisplayName(nbt).getOrElse("") if (Strings.isNullOrEmpty(name)) { name = RobotData.randomName } - totalEnergy = nbt.getInteger(StoredEnergyTag) - robotEnergy = nbt.getInteger(RobotEnergyTag) - tier = nbt.getInteger(TierTag) - components = nbt.getTagList(ComponentsTag, NBT.TAG_COMPOUND). - toArray[NBTTagCompound].map(new ItemStack(_)) - containers = nbt.getTagList(ContainersTag, NBT.TAG_COMPOUND). - toArray[NBTTagCompound].map(new ItemStack(_)) - if (nbt.hasKey(LightColorTag)) { - lightColor = nbt.getInteger(LightColorTag) + totalEnergy = nbt.getInt(StoredEnergyTag) + robotEnergy = nbt.getInt(RobotEnergyTag) + tier = nbt.getInt(TierTag) + components = nbt.getList(ComponentsTag, NBT.TAG_COMPOUND). + toTagArray[CompoundNBT].map(ItemStack.of(_)) + containers = nbt.getList(ContainersTag, NBT.TAG_COMPOUND). + toTagArray[CompoundNBT].map(ItemStack.of(_)) + if (nbt.contains(LightColorTag)) { + lightColor = nbt.getInt(LightColorTag) } } - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { if (!Strings.isNullOrEmpty(name)) { ItemUtils.setDisplayName(nbt, name) } - nbt.setInteger(StoredEnergyTag, totalEnergy) - nbt.setInteger(RobotEnergyTag, robotEnergy) - nbt.setInteger(TierTag, tier) + nbt.putInt(StoredEnergyTag, totalEnergy) + nbt.putInt(RobotEnergyTag, robotEnergy) + nbt.putInt(TierTag, tier) nbt.setNewTagList(ComponentsTag, components.toIterable) nbt.setNewTagList(ContainersTag, containers.toIterable) - nbt.setInteger(LightColorTag, lightColor) + nbt.putInt(LightColorTag, lightColor) } def copyItemStack() = { @@ -96,8 +96,8 @@ class RobotData extends ItemData(Constants.BlockName.Robot) { newInfo.components.foreach(cs => Option(api.Driver.driverFor(cs)) match { case Some(driver) if driver == DriverScreen => val nbt = driver.dataTag(cs) - for (tagName <- nbt.getKeySet.toArray) { - nbt.removeTag(tagName.asInstanceOf[String]) + for (tagName <- nbt.getAllKeys.toArray) { + nbt.remove(tagName.asInstanceOf[String]) } case _ => }) @@ -105,7 +105,7 @@ class RobotData extends ItemData(Constants.BlockName.Robot) { // internal buffer. This is for creative use only, anyway. newInfo.totalEnergy = 0 newInfo.robotEnergy = 50000 - newInfo.save(stack) + newInfo.saveData(stack) stack } } diff --git a/src/main/scala/li/cil/oc/common/item/data/TabletData.scala b/src/main/scala/li/cil/oc/common/item/data/TabletData.scala index 7830d0a438..953c2237cd 100644 --- a/src/main/scala/li/cil/oc/common/item/data/TabletData.scala +++ b/src/main/scala/li/cil/oc/common/item/data/TabletData.scala @@ -5,13 +5,13 @@ import li.cil.oc.Settings import li.cil.oc.common.Tier import li.cil.oc.util.ExtendedNBT._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraftforge.common.util.Constants.NBT class TabletData extends ItemData(Constants.ItemName.Tablet) { def this(stack: ItemStack) { this() - load(stack) + loadData(stack) } var items = Array.fill[ItemStack](32)(ItemStack.EMPTY) @@ -30,36 +30,36 @@ class TabletData extends ItemData(Constants.ItemName.Tablet) { private final val TierTag = Settings.namespace + "tier" private final val ContainerTag = Settings.namespace + "container" - override def load(nbt: NBTTagCompound) { - nbt.getTagList(ItemsTag, NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => { + override def loadData(nbt: CompoundNBT) { + nbt.getList(ItemsTag, NBT.TAG_COMPOUND).foreach((slotNbt: CompoundNBT) => { val slot = slotNbt.getByte(SlotTag) if (slot >= 0 && slot < items.length) { - items(slot) = new ItemStack(slotNbt.getCompoundTag(ItemTag)) + items(slot) = ItemStack.of(slotNbt.getCompound(ItemTag)) } }) isRunning = nbt.getBoolean(IsRunningTag) energy = nbt.getDouble(EnergyTag) maxEnergy = nbt.getDouble(MaxEnergyTag) - tier = nbt.getInteger(TierTag) - if (nbt.hasKey(ContainerTag)) { - container = new ItemStack(nbt.getCompoundTag(ContainerTag)) + tier = nbt.getInt(TierTag) + if (nbt.contains(ContainerTag)) { + container = ItemStack.of(nbt.getCompound(ContainerTag)) } } - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { nbt.setNewTagList(ItemsTag, items.zipWithIndex collect { case (stack, slot) if !stack.isEmpty => (stack, slot) } map { case (stack, slot) => - val slotNbt = new NBTTagCompound() - slotNbt.setByte(SlotTag, slot.toByte) - slotNbt.setNewCompoundTag(ItemTag, stack.writeToNBT) + val slotNbt = new CompoundNBT() + slotNbt.putByte(SlotTag, slot.toByte) + slotNbt.setNewCompoundTag(ItemTag, stack.save) }) - nbt.setBoolean(IsRunningTag, isRunning) - nbt.setDouble(EnergyTag, energy) - nbt.setDouble(MaxEnergyTag, maxEnergy) - nbt.setInteger(TierTag, tier) - if (!container.isEmpty) nbt.setNewCompoundTag(ContainerTag, container.writeToNBT) + nbt.putBoolean(IsRunningTag, isRunning) + nbt.putDouble(EnergyTag, energy) + nbt.putDouble(MaxEnergyTag, maxEnergy) + nbt.putInt(TierTag, tier) + if (!container.isEmpty) nbt.setNewCompoundTag(ContainerTag, container.save) } } diff --git a/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala b/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala index 61b7245437..0ae5fda690 100644 --- a/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala +++ b/src/main/scala/li/cil/oc/common/item/traits/CPULike.scala @@ -7,29 +7,34 @@ import li.cil.oc.api import li.cil.oc.api.driver.item.MutableProcessor import li.cil.oc.integration.opencomputers.DriverCPU import li.cil.oc.util.Tooltip -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand -import net.minecraft.util.text.TextComponentTranslation +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand +import net.minecraft.util.Util +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.util.text.TranslationTextComponent import net.minecraft.world.World -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.language.existentials -trait CPULike extends Delegate { +trait CPULike extends SimpleItem { def cpuTier: Int override protected def tooltipData: Seq[Any] = Seq(Settings.get.cpuComponentSupport(cpuTier)) - override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]) { - tooltip.addAll(Tooltip.get("cpu.Architecture", api.Machine.getArchitectureName(DriverCPU.architecture(stack)))) + override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[ITextComponent]) { + for (curr <- Tooltip.get("cpu.Architecture", api.Machine.getArchitectureName(DriverCPU.architecture(stack)))) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (player.isSneaking) { - if (!world.isRemote) { + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (player.isCrouching) { + if (!world.isClientSide) { api.Driver.driverFor(stack) match { case driver: MutableProcessor => val architectures = driver.allArchitectures.toList @@ -39,13 +44,13 @@ trait CPULike extends Delegate { val archClass = architectures(newIndex) val archName = api.Machine.getArchitectureName(archClass) driver.setArchitecture(stack, archClass) - player.sendMessage(new TextComponentTranslation(Settings.namespace + "tooltip.cpu.Architecture", archName)) + player.sendMessage(new TranslationTextComponent(Settings.namespace + "tooltip.cpu.Architecture", archName), Util.NIL_UUID) } - player.swingArm(EnumHand.MAIN_HAND) + player.swing(Hand.MAIN_HAND) case _ => // No known driver for this processor. } } } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) } } diff --git a/src/main/scala/li/cil/oc/common/item/traits/Chargeable.scala b/src/main/scala/li/cil/oc/common/item/traits/Chargeable.scala index c32f1c5aa1..f9dad6ab46 100644 --- a/src/main/scala/li/cil/oc/common/item/traits/Chargeable.scala +++ b/src/main/scala/li/cil/oc/common/item/traits/Chargeable.scala @@ -1,21 +1,16 @@ package li.cil.oc.common.item.traits -import ic2.api.item.IElectricItemManager import li.cil.oc.{Settings, api} -import li.cil.oc.common.asm.Injectable import li.cil.oc.integration.Mods -import li.cil.oc.integration.ic2.ElectricItemManager import li.cil.oc.integration.opencomputers.ModOpenComputers -import net.minecraft.util.{EnumFacing, ResourceLocation} -import net.minecraftforge.fml.common.Optional +import net.minecraft.util.{Direction, ResourceLocation} import net.minecraft.item.ItemStack import net.minecraftforge.common.capabilities.{Capability, ICapabilityProvider} import net.minecraftforge.energy.{CapabilityEnergy, IEnergyStorage} +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier // TODO Forge power capabilities. -@Injectable.InterfaceList(Array( - new Injectable.Interface(value = "ic2.api.item.ISpecialElectricItem", modid = Mods.IDs.IndustrialCraft2) -)) trait Chargeable extends api.driver.item.Chargeable { def maxCharge(stack: ItemStack): Double @@ -25,9 +20,6 @@ trait Chargeable extends api.driver.item.Chargeable { def setCharge(stack: ItemStack, amount: Double): Unit def canExtract(stack: ItemStack): Boolean = false - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2) - def getManager(stack: ItemStack): IElectricItemManager = ElectricItemManager } object Chargeable { @@ -48,14 +40,16 @@ object Chargeable { unused } - class Provider(stack: ItemStack, item: li.cil.oc.common.item.traits.Chargeable) extends ICapabilityProvider with IEnergyStorage { - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { - capability == CapabilityEnergy.ENERGY - } + class Provider(stack: ItemStack, item: li.cil.oc.common.item.traits.Chargeable) extends ICapabilityProvider with NonNullSupplier[Provider] with IEnergyStorage { + private val wrapper = LazyOptional.of(this) + + def get = this + + def invalidate() = wrapper.invalidate - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { - if (hasCapability(capability, facing)) this.asInstanceOf[T] - else null.asInstanceOf[T] + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { + if (capability == CapabilityEnergy.ENERGY) wrapper.cast[T] + else LazyOptional.empty[T] } def receiveEnergy(maxReceive: Int, simulate: Boolean): Int = diff --git a/src/main/scala/li/cil/oc/common/item/traits/Delegate.scala b/src/main/scala/li/cil/oc/common/item/traits/Delegate.scala deleted file mode 100644 index ce6bb9b06a..0000000000 --- a/src/main/scala/li/cil/oc/common/item/traits/Delegate.scala +++ /dev/null @@ -1,107 +0,0 @@ -package li.cil.oc.common.item.traits - -import java.util - -import li.cil.oc.Settings -import li.cil.oc.api -import li.cil.oc.api.driver.DriverItem -import li.cil.oc.common.item.Delegator -import li.cil.oc.util.BlockPosition -import li.cil.oc.util.Rarity -import li.cil.oc.util.Tooltip -import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.EnumAction -import net.minecraft.item.EnumRarity -import net.minecraft.item.ItemStack -import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess -import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -trait Delegate { - def parent: Delegator - - def unlocalizedName: String = getClass.getSimpleName.toLowerCase - - protected def tooltipName = Option(unlocalizedName) - - protected def tooltipData = Seq.empty[Any] - - var showInItemList = true - - val itemId: Int = parent.add(this) - - def maxStackSize = 64 - - def createItemStack(amount: Int = 1) = new ItemStack(parent, amount, itemId) - - // ----------------------------------------------------------------------- // - - def doesSneakBypassUse(world: IBlockAccess, pos: BlockPos, player: EntityPlayer) = false - - def onItemUseFirst(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): EnumActionResult = EnumActionResult.PASS - - def onItemUse(stack: ItemStack, player: EntityPlayer, position: BlockPosition, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = false - - def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = ActionResult.newResult(EnumActionResult.PASS, stack) - - def getItemUseAction(stack: ItemStack): EnumAction = EnumAction.NONE - - def getMaxItemUseDuration(stack: ItemStack) = 0 - - def onItemUseFinish(stack: ItemStack, world: World, player: EntityLivingBase): ItemStack = stack - - def onPlayerStoppedUsing(stack: ItemStack, player: EntityLivingBase, duration: Int) {} - - def update(stack: ItemStack, world: World, player: Entity, slot: Int, selected: Boolean) {} - - // ----------------------------------------------------------------------- // - - def rarity(stack: ItemStack): EnumRarity = Rarity.byTier(tierFromDriver(stack)) - - protected def tierFromDriver(stack: ItemStack): Int = - api.Driver.driverFor(stack) match { - case driver: DriverItem => driver.tier(stack) - case _ => 0 - } - - def color(stack: ItemStack, pass: Int) = 0xFFFFFF - - def getContainerItem(stack: ItemStack): ItemStack = ItemStack.EMPTY - - def hasContainerItem(stack: ItemStack): Boolean = false - - def displayName(stack: ItemStack): Option[String] = None - - @SideOnly(Side.CLIENT) - def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - if (tooltipName.isDefined) { - tooltip.addAll(Tooltip.get(tooltipName.get, tooltipData: _*)) - tooltipExtended(stack, tooltip) - } - tooltipCosts(stack, tooltip) - } - - // For stuff that goes to the normal 'extended' tooltip, before the costs. - protected def tooltipExtended(stack: ItemStack, tooltip: java.util.List[String]) {} - - protected def tooltipCosts(stack: ItemStack, tooltip: java.util.List[String]) { - if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data")) { - val data = stack.getTagCompound.getCompoundTag(Settings.namespace + "data") - if (data.hasKey("node") && data.getCompoundTag("node").hasKey("address")) { - tooltip.add("§8" + data.getCompoundTag("node").getString("address").substring(0, 13) + "...§7") - } - } - } - - def showDurabilityBar(stack: ItemStack) = false - - def durability(stack: ItemStack) = 0.0 -} diff --git a/src/main/scala/li/cil/oc/common/item/traits/FileSystemLike.scala b/src/main/scala/li/cil/oc/common/item/traits/FileSystemLike.scala index c4fd815d66..b07e363ac9 100644 --- a/src/main/scala/li/cil/oc/common/item/traits/FileSystemLike.scala +++ b/src/main/scala/li/cil/oc/common/item/traits/FileSystemLike.scala @@ -5,49 +5,61 @@ import java.util import li.cil.oc.Localization import li.cil.oc.OpenComputers import li.cil.oc.Settings -import li.cil.oc.common.GuiType -import net.minecraft.client.util.ITooltipFlag +import li.cil.oc.client.gui import li.cil.oc.common.item.data.DriveData -import net.minecraft.entity.player.EntityPlayer +import li.cil.oc.util.Tooltip +import net.minecraft.client.Minecraft +import net.minecraft.client.util.ITooltipFlag +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.util.ActionResult -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumHand +import net.minecraft.util.ActionResultType +import net.minecraft.util.Hand +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -trait FileSystemLike extends Delegate { +trait FileSystemLike extends SimpleItem { override protected def tooltipName = None def kiloBytes: Int - override def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag): Unit = { - if (stack.hasTagCompound) { - val nbt = stack.getTagCompound - if (nbt.hasKey(Settings.namespace + "data")) { - val data = nbt.getCompoundTag(Settings.namespace + "data") - if (data.hasKey(Settings.namespace + "fs.label")) { - tooltip.add(data.getString(Settings.namespace + "fs.label")) + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) + if (stack.hasTag) { + val nbt = stack.getTag + if (nbt.contains(Settings.namespace + "data")) { + val data = nbt.getCompound(Settings.namespace + "data") + if (data.contains(Settings.namespace + "fs.label")) { + tooltip.add(new StringTextComponent(data.getString(Settings.namespace + "fs.label")).setStyle(Tooltip.DefaultStyle)) } - if (flag.isAdvanced && data.hasKey("fs")) { - val fsNbt = data.getCompoundTag("fs") - if (fsNbt.hasKey("capacity.used")) { + if (flag.isAdvanced && data.contains("fs")) { + val fsNbt = data.getCompound("fs") + if (fsNbt.contains("capacity.used")) { val used = fsNbt.getLong("capacity.used") - tooltip.add(Localization.Tooltip.DiskUsage(used, kiloBytes * 1024)) + tooltip.add(new StringTextComponent(Localization.Tooltip.DiskUsage(used, kiloBytes * 1024)).setStyle(Tooltip.DefaultStyle)) } } } val data = new DriveData(stack) - tooltip.add(Localization.Tooltip.DiskMode(data.isUnmanaged)) - tooltip.add(Localization.Tooltip.DiskLock(data.lockInfo)) + tooltip.add(new StringTextComponent(Localization.Tooltip.DiskMode(data.isUnmanaged)).setStyle(Tooltip.DefaultStyle)) + tooltip.add(new StringTextComponent(Localization.Tooltip.DiskLock(data.lockInfo)).setStyle(Tooltip.DefaultStyle)) } - super.tooltipLines(stack, world, tooltip, flag) } - override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ActionResult[ItemStack] = { - if (!player.isSneaking && (!stack.hasTagCompound || !stack.getTagCompound.hasKey(Settings.namespace + "lootFactory"))) { - player.openGui(OpenComputers, GuiType.Drive.id, world, 0, 0, 0) - player.swingArm(EnumHand.MAIN_HAND) + override def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = { + if (!player.isCrouching && (!stack.hasTag || !stack.getTag.contains(Settings.namespace + "lootFactory"))) { + if (world.isClientSide) showGui(stack, player) + player.swing(Hand.MAIN_HAND) } - ActionResult.newResult(EnumActionResult.SUCCESS, stack) + new ActionResult(ActionResultType.sidedSuccess(world.isClientSide), stack) + } + + @OnlyIn(Dist.CLIENT) + private def showGui(stack: ItemStack, player: PlayerEntity) { + Minecraft.getInstance.pushGuiLayer(new gui.Drive(player.inventory, () => stack)) } } diff --git a/src/main/scala/li/cil/oc/common/item/traits/GPULike.scala b/src/main/scala/li/cil/oc/common/item/traits/GPULike.scala index ffd255ef6d..73f2ec3c6c 100644 --- a/src/main/scala/li/cil/oc/common/item/traits/GPULike.scala +++ b/src/main/scala/li/cil/oc/common/item/traits/GPULike.scala @@ -3,7 +3,7 @@ package li.cil.oc.common.item.traits import li.cil.oc.Settings import li.cil.oc.util.PackedColor -trait GPULike extends Delegate { +trait GPULike extends SimpleItem { def gpuTier: Int override protected def tooltipData: Seq[Any] = { diff --git a/src/main/scala/li/cil/oc/common/item/traits/ItemTier.scala b/src/main/scala/li/cil/oc/common/item/traits/ItemTier.scala index f499f96775..74c63c681e 100644 --- a/src/main/scala/li/cil/oc/common/item/traits/ItemTier.scala +++ b/src/main/scala/li/cil/oc/common/item/traits/ItemTier.scala @@ -3,20 +3,22 @@ package li.cil.oc.common.item.traits import java.util import li.cil.oc.Localization +import li.cil.oc.util.Tooltip import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -trait ItemTier extends Delegate { - self: Delegate => - @SideOnly(Side.CLIENT) - override def tooltipLines(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - super.tooltipLines(stack, world, tooltip, flag) +trait ItemTier extends SimpleItem { + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + super.appendHoverText(stack, world, tooltip, flag) if (flag.isAdvanced) { - tooltip.add(Localization.Tooltip.Tier(tierFromDriver(stack) + 1)) + tooltip.add(new StringTextComponent(Localization.Tooltip.Tier(tierFromDriver(stack) + 1)).setStyle(Tooltip.DefaultStyle)) } } } diff --git a/src/main/scala/li/cil/oc/common/item/traits/SimpleItem.scala b/src/main/scala/li/cil/oc/common/item/traits/SimpleItem.scala index 2c85eafa62..0e6ca4b855 100644 --- a/src/main/scala/li/cil/oc/common/item/traits/SimpleItem.scala +++ b/src/main/scala/li/cil/oc/common/item/traits/SimpleItem.scala @@ -2,43 +2,133 @@ package li.cil.oc.common.item.traits import java.util -import li.cil.oc.CreativeTab +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.api.event.RobotRenderEvent.MountPoint +import li.cil.oc.api.internal.Robot +import li.cil.oc.client.renderer.item.UpgradeRenderer import li.cil.oc.common.tileentity +import li.cil.oc.integration.opencomputers.{Item => OpenComputersItem} +import li.cil.oc.util.BlockPosition import li.cil.oc.util.Tooltip +import net.minecraft.client.renderer.IRenderTypeBuffer import net.minecraft.client.util.ITooltipFlag -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.item.BlockItemUseContext import net.minecraft.item.Item +import net.minecraft.item.Item.Properties import net.minecraft.item.ItemStack +import net.minecraft.item.ItemUseContext +import net.minecraft.util.ActionResult +import net.minecraft.util.ActionResultType +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.IWorldReader import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -trait SimpleItem extends Item { - setCreativeTab(CreativeTab) +import scala.collection.convert.ImplicitConversionsToScala._ +trait SimpleItem extends Item with api.driver.item.UpgradeRenderer { def createItemStack(amount: Int = 1) = new ItemStack(this, amount) - override def isBookEnchantable(stack: ItemStack, book: ItemStack) = false + @Deprecated + protected var unlocalizedName = getClass.getSimpleName.toLowerCase - override def doesSneakBypassUse(stack: ItemStack, world: IBlockAccess, pos: BlockPos, player: EntityPlayer): Boolean = { - world.getTileEntity(pos) match { + @Deprecated + override def getDescriptionId = "item.oc." + unlocalizedName + + override def doesSneakBypassUse(stack: ItemStack, world: IWorldReader, pos: BlockPos, player: PlayerEntity): Boolean = { + world.getBlockEntity(pos) match { case drive: tileentity.DiskDrive => true case _ => super.doesSneakBypassUse(stack, world, pos, player) } } - @SideOnly(Side.CLIENT) - override def addInformation(stack: ItemStack, world: World, tooltip: util.List[String], flag: ITooltipFlag) { - tooltip.addAll(Tooltip.get(getClass.getSimpleName.toLowerCase)) + @Deprecated + override def onItemUseFirst(stack: ItemStack, ctx: ItemUseContext): ActionResultType = { + val pos = ctx.getClickedPos + val hitPos = ctx.getClickLocation + onItemUseFirst(stack, ctx.getPlayer, ctx.getPlayer.level, pos, ctx.getClickedFace, + (hitPos.x - pos.getX).toFloat, (hitPos.y - pos.getY).toFloat, (hitPos.z - pos.getZ).toFloat, ctx.getHand) + } + + @Deprecated + def onItemUseFirst(stack: ItemStack, player: PlayerEntity, world: World, pos: BlockPos, side: Direction, hitX: Float, hitY: Float, hitZ: Float, hand: Hand): ActionResultType = ActionResultType.PASS + + @Deprecated + override def useOn(ctx: ItemUseContext): ActionResultType = + ctx.getItemInHand match { + case stack: ItemStack => { + val world = ctx.getLevel + val pos = BlockPosition(ctx.getClickedPos, world) + val hitPos = ctx.getClickLocation + val success = onItemUse(stack, ctx.getPlayer, pos, ctx.getClickedFace, + (hitPos.x - pos.x).toFloat, (hitPos.y - pos.y).toFloat, (hitPos.z - pos.z).toFloat) + if (success) ActionResultType.sidedSuccess(world.isClientSide) else ActionResultType.PASS + } + case _ => super.useOn(ctx) + } + + @Deprecated + def onItemUse(stack: ItemStack, player: PlayerEntity, position: BlockPosition, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = false + + @Deprecated + override def use(world: World, player: PlayerEntity, hand: Hand): ActionResult[ItemStack] = + player.getItemInHand(hand) match { + case stack: ItemStack => use(stack, world, player) + case _ => super.use(world, player, hand) + } + + @Deprecated + def use(stack: ItemStack, world: World, player: PlayerEntity): ActionResult[ItemStack] = new ActionResult(ActionResultType.PASS, stack) + + protected def tierFromDriver(stack: ItemStack): Int = + api.Driver.driverFor(stack) match { + case driver: api.driver.DriverItem => driver.tier(stack) + case _ => 0 + } + + protected def tooltipName = Option(unlocalizedName) + + protected def tooltipData = Seq.empty[Any] + + @OnlyIn(Dist.CLIENT) + override def appendHoverText(stack: ItemStack, world: World, tooltip: util.List[ITextComponent], flag: ITooltipFlag) { + if (tooltipName.isDefined) { + for (curr <- Tooltip.get(tooltipName.get, tooltipData: _*)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } + tooltipExtended(stack, tooltip) + } + else { + for (curr <- Tooltip.get(getClass.getSimpleName.toLowerCase)) { + tooltip.add(new StringTextComponent(curr).setStyle(Tooltip.DefaultStyle)) + } + } + tooltipCosts(stack, tooltip) + } + + // For stuff that goes to the normal 'extended' tooltip, before the costs. + protected def tooltipExtended(stack: ItemStack, tooltip: java.util.List[ITextComponent]) {} - if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "data")) { - val data = stack.getTagCompound.getCompoundTag(Settings.namespace + "data") - if (data.hasKey("node") && data.getCompoundTag("node").hasKey("address")) { - tooltip.add("§8" + data.getCompoundTag("node").getString("address").substring(0, 13) + "...§7") + protected def tooltipCosts(stack: ItemStack, tooltip: java.util.List[ITextComponent]) { + if (stack.hasTag && stack.getTag.contains(Settings.namespace + "data")) { + val data = stack.getTag.getCompound(Settings.namespace + "data") + if (data.contains("node") && data.getCompound("node").contains("address")) { + tooltip.add(new StringTextComponent("§8" + data.getCompound("node").getString("address").substring(0, 13) + "...§7")) } } } + + // ----------------------------------------------------------------------- // + + override def computePreferredMountPoint(stack: ItemStack, robot: Robot, availableMountPoints: util.Set[String]): String = UpgradeRenderer.preferredMountPoint(stack, availableMountPoints) + + override def render(matrix: MatrixStack, buffer: IRenderTypeBuffer, stack: ItemStack, mountPoint: MountPoint, robot: Robot, pt: Float): Unit = UpgradeRenderer.render(matrix, buffer, stack, mountPoint) } diff --git a/src/main/scala/li/cil/oc/common/launch/CoreModContainer.scala b/src/main/scala/li/cil/oc/common/launch/CoreModContainer.scala deleted file mode 100644 index afab110fd9..0000000000 --- a/src/main/scala/li/cil/oc/common/launch/CoreModContainer.scala +++ /dev/null @@ -1,19 +0,0 @@ -package li.cil.oc.common.launch - -import com.google.common.eventbus.EventBus -import net.minecraftforge.fml.common.DummyModContainer -import net.minecraftforge.fml.common.LoadController -import net.minecraftforge.fml.common.ModMetadata - -class CoreModContainer extends DummyModContainer({ - val md = new ModMetadata() - md.authorList.add("Sangar") - md.modId = "opencomputers|core" - md.version = "@VERSION@" - md.name = "OpenComputers (Core)" - md.url = "https://oc.cil.li/" - md.description = "OC core mod used for class transformer and as API owner to avoid cyclic dependencies." - md -}) { - override def registerBus(bus: EventBus, controller: LoadController) = true -} diff --git a/src/main/scala/li/cil/oc/common/launch/TransformerLoader.scala b/src/main/scala/li/cil/oc/common/launch/TransformerLoader.scala deleted file mode 100644 index 1b27f4a649..0000000000 --- a/src/main/scala/li/cil/oc/common/launch/TransformerLoader.scala +++ /dev/null @@ -1,23 +0,0 @@ -package li.cil.oc.common.launch - -import java.util - -import li.cil.oc.common.asm.ClassTransformer -import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin -import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin.{SortingIndex, TransformerExclusions} - -@SortingIndex(1001) -@TransformerExclusions(Array("li.cil.oc.common.asm")) -class TransformerLoader extends IFMLLoadingPlugin { - val instance = this - - override def getModContainerClass = "li.cil.oc.common.launch.CoreModContainer" - - override def getASMTransformerClass = Array(classOf[ClassTransformer].getName) - - override def getAccessTransformerClass = null - - override def getSetupClass = null - - override def injectData(data: util.Map[String, AnyRef]) {} -} diff --git a/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala b/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala index c419650c9d..b881c78a6c 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/ControllerImpl.scala @@ -21,29 +21,30 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.PlayerUtils -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.potion.Potion -import net.minecraft.potion.PotionEffect -import net.minecraft.util.EnumParticleTypes +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.particles.ParticleTypes +import net.minecraft.potion.Effect +import net.minecraft.potion.Effects +import net.minecraft.potion.EffectInstance import net.minecraft.util.ResourceLocation import net.minecraft.world.World -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable -class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessEndpoint { +class ControllerImpl(val player: PlayerEntity) extends Controller with WirelessEndpoint { if (isServer) api.Network.joinWirelessNetwork(this) - var previousDimension = player.world.provider.getDimension + var previousDimension = player.level.dimension lazy val CommandRange = Settings.get.nanomachinesCommandRange * Settings.get.nanomachinesCommandRange final val FullSyncInterval = 20 * 60 final val OverloadDamage = new DamageSourceWithRandomCause("oc.nanomachinesOverload", 3). - setDamageBypassesArmor(). - setDamageIsAbsolute() + bypassArmor(). + bypassMagic() var uuid = UUID.randomUUID.toString var responsePort = 0 @@ -56,7 +57,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE var activeBehaviorsDirty = true var hasSentConfiguration = false - override def world: World = player.getEntityWorld + override def world: World = player.level override def x: Int = BlockPosition(player).x @@ -65,8 +66,8 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE override def z: Int = BlockPosition(player).z override def receivePacket(packet: Packet, sender: WirelessEndpoint): Unit = { - if (getLocalBuffer > 0 && commandDelay < 1 && !player.isDead) { - val (dx, dy, dz) = ((sender.x + 0.5) - player.posX, (sender.y + 0.5) - player.posY, (sender.z + 0.5) - player.posZ) + if (getLocalBuffer > 0 && commandDelay < 1 && player.isAlive) { + val (dx, dy, dz) = ((sender.x + 0.5) - player.getX, (sender.y + 0.5) - player.getY, (sender.z + 0.5) - player.getZ) val dSquared = Math.sqrt(dx * dx + dy * dy + dz * dz) if (dSquared <= CommandRange) packet.data.headOption match { case Some(header: Array[Byte]) if new String(header, Charsets.UTF_8) == "nanomachines" => @@ -83,11 +84,11 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE case Array("saveConfiguration") => val nanomachines = api.Items.get(Constants.ItemName.Nanomachines) try { - val index = player.inventory.mainInventory.indexWhere(stack => api.Items.get(stack) == nanomachines && new NanomachineData(stack).configuration.isEmpty) + val index = player.inventory.items.indexWhere(stack => api.Items.get(stack) == nanomachines && new NanomachineData(stack).configuration.isEmpty) if (index >= 0) { - val stack = player.inventory.decrStackSize(index, 1) - new NanomachineData(this).save(stack) - player.inventory.addItemStackToInventory(stack) + val stack = player.inventory.removeItem(index, 1) + new NanomachineData(this).saveData(stack) + player.inventory.add(stack) InventoryUtils.spawnStackInWorld(BlockPosition(player), stack) respond(sender, "saved", true) } @@ -100,11 +101,11 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE case Array("getHealth") => respond(sender, "health", player.getHealth, player.getMaxHealth) case Array("getHunger") => - respond(sender, "hunger", player.getFoodStats.getFoodLevel, player.getFoodStats.getSaturationLevel) + respond(sender, "hunger", player.getFoodData.getFoodLevel, player.getFoodData.getSaturationLevel) case Array("getAge") => - respond(sender, "age", (player.getIdleTime / 20f).toInt) + respond(sender, "age", (player.getNoActionTime / 20f).toInt) case Array("getName") => - respond(sender, "name", player.getDisplayName.getUnformattedComponentText) + respond(sender, "name", player.getDisplayName.getString) case Array("getExperience") => respond(sender, "experience", player.experienceLevel) @@ -171,10 +172,10 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE activeBehaviorsDirty = true player match { - case playerMP: EntityPlayerMP if playerMP.connection != null => - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("blindness"), 100)) - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("poison"), 150)) - player.addPotionEffect(new PotionEffect(Potion.getPotionFromResourceLocation("slowness"), 200)) + case playerMP: ServerPlayerEntity if playerMP.connection != null => + player.addEffect(new EffectInstance(Effects.BLINDNESS, 100)) + player.addEffect(new EffectInstance(Effects.POISON, 150)) + player.addEffect(new EffectInstance(Effects.MOVEMENT_SLOWDOWN, 200)) changeBuffer(-Settings.get.nanomachineReconfigureCost) hasSentConfiguration = false @@ -217,7 +218,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE override def changeBuffer(delta: Double): Double = { if (isClient) delta - else if (delta < 0 && (Settings.get.ignorePower || player.capabilities.isCreativeMode)) 0.0 + else if (delta < 0 && (Settings.get.ignorePower || player.isCreative)) 0.0 else { val newValue = storedEnergy + delta storedEnergy = math.min(math.max(newValue, 0), getLocalBufferSize) @@ -228,7 +229,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE // ----------------------------------------------------------------------- // def update(): Unit = { - if (player.isDead) { + if (!player.isAlive) { return } @@ -245,10 +246,10 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE // load is called while the world is still set to the overworld, but // no dimension change event is fired if the player actually logged // out in another dimension... yay) - if (player.world.provider.getDimension != previousDimension) { + if (player.level.dimension != previousDimension) { api.Network.leaveWirelessNetwork(this, previousDimension) api.Network.joinWirelessNetwork(this) - previousDimension = player.world.provider.getDimension + previousDimension = player.level.dimension } else { api.Network.updateWirelessNetwork(this) @@ -271,14 +272,14 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE active.foreach(_.update()) if (isServer) { - if (player.getEntityWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (player.level.getGameTime % Settings.get.tickFrequency == 0) { changeBuffer(-Settings.get.nanomachineCost * Settings.get.tickFrequency * (activeInputs + 0.5)) PacketSender.sendNanomachinePower(player) } val overload = activeInputs - getSafeActiveInputs - if (!player.capabilities.isCreativeMode && overload > 0 && player.getEntityWorld.getTotalWorldTime % 20 == 0) { - player.attackEntityFrom(OverloadDamage, overload) + if (!player.isCreative && overload > 0 && player.level.getGameTime % 20 == 0) { + player.hurt(OverloadDamage, overload) } } @@ -286,7 +287,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE val energyRatio = getLocalBuffer / (getLocalBufferSize + 1) val triggerRatio = activeInputs / (configuration.triggers.length + 1) val intensity = (energyRatio + triggerRatio) * 0.25 - PlayerUtils.spawnParticleAround(player, EnumParticleTypes.PORTAL, intensity) + PlayerUtils.spawnParticleAround(player, ParticleTypes.PORTAL, intensity) } } @@ -299,7 +300,7 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE // Send a full sync every now and then, e.g. for other players coming // closer that weren't there to get the initial info for an enabled // input. - if (!hasSentConfiguration || player.getEntityWorld.getTotalWorldTime % FullSyncInterval == 0) { + if (!hasSentConfiguration || player.level.getGameTime % FullSyncInterval == 0) { hasSentConfiguration = true PacketSender.sendNanomachineConfiguration(player) } @@ -340,24 +341,24 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE // ----------------------------------------------------------------------- // - def save(nbt: NBTTagCompound): Unit = configuration.synchronized { - nbt.setString("uuid", uuid) - nbt.setInteger("port", responsePort) - nbt.setDouble("energy", storedEnergy) - nbt.setNewCompoundTag("configuration", configuration.save) + def saveData(nbt: CompoundNBT): Unit = configuration.synchronized { + nbt.putString("uuid", uuid) + nbt.putInt("port", responsePort) + nbt.putDouble("energy", storedEnergy) + nbt.setNewCompoundTag("configuration", configuration.saveData) } - def load(nbt: NBTTagCompound): Unit = configuration.synchronized { + def loadData(nbt: CompoundNBT): Unit = configuration.synchronized { uuid = nbt.getString("uuid") - responsePort = nbt.getInteger("port") + responsePort = nbt.getInt("port") storedEnergy = nbt.getDouble("energy") - configuration.load(nbt.getCompoundTag("configuration")) + configuration.loadData(nbt.getCompound("configuration")) activeBehaviorsDirty = true } // ----------------------------------------------------------------------- // - private def isClient = world.isRemote + private def isClient = world.isClientSide private def isServer = !isClient @@ -365,8 +366,8 @@ class ControllerImpl(val player: EntityPlayer) extends Controller with WirelessE if (activeBehaviorsDirty) { configuration.synchronized(if (activeBehaviorsDirty) { val newBehaviors = configuration.behaviors.filter(_.isActive).map(_.behavior) - val addedBehaviors = newBehaviors -- activeBehaviors - val removedBehaviors = activeBehaviors -- newBehaviors + val addedBehaviors = newBehaviors.clone --= activeBehaviors + val removedBehaviors = activeBehaviors.clone --= newBehaviors activeBehaviors.clear() activeBehaviors ++= newBehaviors activeBehaviorsDirty = false diff --git a/src/main/scala/li/cil/oc/common/nanomachines/Nanomachines.scala b/src/main/scala/li/cil/oc/common/nanomachines/Nanomachines.scala index c166b696a0..c05ad7fb77 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/Nanomachines.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/Nanomachines.scala @@ -6,46 +6,46 @@ import li.cil.oc.api.nanomachines.BehaviorProvider import li.cil.oc.api.nanomachines.Controller import li.cil.oc.server.PacketSender import li.cil.oc.util.PlayerUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable object Nanomachines extends api.detail.NanomachinesAPI { val providers = mutable.Set.empty[BehaviorProvider] - val serverControllers: mutable.WeakHashMap[EntityPlayer, ControllerImpl] = mutable.WeakHashMap.empty[EntityPlayer, ControllerImpl] - val clientControllers: mutable.WeakHashMap[EntityPlayer, ControllerImpl] = mutable.WeakHashMap.empty[EntityPlayer, ControllerImpl] + val serverControllers: mutable.WeakHashMap[PlayerEntity, ControllerImpl] = mutable.WeakHashMap.empty[PlayerEntity, ControllerImpl] + val clientControllers: mutable.WeakHashMap[PlayerEntity, ControllerImpl] = mutable.WeakHashMap.empty[PlayerEntity, ControllerImpl] - def controllers(player: EntityPlayer): mutable.WeakHashMap[EntityPlayer, ControllerImpl] = if (player.getEntityWorld.isRemote) clientControllers else serverControllers + def controllers(player: PlayerEntity): mutable.WeakHashMap[PlayerEntity, ControllerImpl] = if (player.level.isClientSide) clientControllers else serverControllers override def addProvider(provider: BehaviorProvider): Unit = providers += provider override def getProviders: java.lang.Iterable[BehaviorProvider] = providers - def getController(player: EntityPlayer): Controller = { + def getController(player: PlayerEntity): Controller = { if (hasController(player)) controllers(player).getOrElseUpdate(player, new ControllerImpl(player)) else null } - def hasController(player: EntityPlayer): Boolean = { + def hasController(player: PlayerEntity): Boolean = { PlayerUtils.persistedData(player).getBoolean(Settings.namespace + "hasNanomachines") } - def installController(player: EntityPlayer): Controller = { + def installController(player: PlayerEntity): Controller = { if (!hasController(player)) { - PlayerUtils.persistedData(player).setBoolean(Settings.namespace + "hasNanomachines", true) + PlayerUtils.persistedData(player).putBoolean(Settings.namespace + "hasNanomachines", true) } getController(player) // Initialize controller instance. } - override def uninstallController(player: EntityPlayer): Unit = { + override def uninstallController(player: PlayerEntity): Unit = { getController(player) match { case controller: ControllerImpl => controller.dispose() controllers(player) -= player - PlayerUtils.persistedData(player).removeTag(Settings.namespace + "hasNanomachines") - if (!player.getEntityWorld.isRemote) { + PlayerUtils.persistedData(player).remove(Settings.namespace + "hasNanomachines") + if (!player.level.isClientSide) { PacketSender.sendNanomachineConfiguration(player) } case _ => // Doesn't have one anyway. diff --git a/src/main/scala/li/cil/oc/common/nanomachines/NeuralNetwork.scala b/src/main/scala/li/cil/oc/common/nanomachines/NeuralNetwork.scala index a172acd030..6d85d834e2 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/NeuralNetwork.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/NeuralNetwork.scala @@ -8,14 +8,15 @@ import li.cil.oc.api.nanomachines.Behavior import li.cil.oc.api.nanomachines.BehaviorProvider import li.cil.oc.server.PacketSender import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.text.TextComponentString +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Util +import net.minecraft.util.text.StringTextComponent import net.minecraft.util.text.TextFormatting import net.minecraftforge.common.util.Constants.NBT -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable import scala.util.Random @@ -58,7 +59,7 @@ class NeuralNetwork(controller: ControllerImpl) extends Persistable { } // Build connections. - val rng = new Random(controller.player.getEntityWorld.rand.nextInt()) + val rng = new Random(controller.player.level.random.nextInt()) def connect[Sink <: ConnectorNeuron, Source <: Neuron](sinks: Iterable[Sink], sources: mutable.ArrayBuffer[Source]): Unit = { // Shuffle sink list to give each entry the same chance. @@ -99,10 +100,10 @@ class NeuralNetwork(controller: ControllerImpl) extends Persistable { // Enter debug configuration, one input -> one behavior, and list mapping in console. def debug(): Unit = { val log = controller.player match { - case playerMP: EntityPlayerMP => (s: String) => PacketSender.sendClientLog(s, playerMP) + case playerMP: ServerPlayerEntity => (s: String) => PacketSender.sendClientLog(s, playerMP) case _ => (s: String) => OpenComputers.log.info(s) } - log(s"Creating debug configuration for nanomachines in player ${controller.player.getDisplayName}.") + log(s"Creating debug configuration for nanomachines in player ${controller.player.getDisplayName.getString}.") behaviors.clear() behaviors ++= api.Nanomachines.getProviders. @@ -123,7 +124,7 @@ class NeuralNetwork(controller: ControllerImpl) extends Persistable { } } - def print(player: EntityPlayer): Unit = { + def print(player: PlayerEntity): Unit = { val sb = StringBuilder.newBuilder def colored(value: Any, enabled: Boolean) = { if (enabled) sb.append(TextFormatting.GREEN) @@ -153,13 +154,13 @@ class NeuralNetwork(controller: ControllerImpl) extends Persistable { } } sb.append(")") - player.sendMessage(new TextComponentString(sb.toString())) + player.sendMessage(new StringTextComponent(sb.toString()), Util.NIL_UUID) sb.clear() } } - override def save(nbt: NBTTagCompound): Unit = { - save(nbt, forItem = false) + override def saveData(nbt: CompoundNBT): Unit = { + saveData(nbt, forItem = false) } private final val TriggersTag = "triggers" @@ -170,46 +171,46 @@ class NeuralNetwork(controller: ControllerImpl) extends Persistable { private final val TriggerInputsTag = "triggerInputs" private final val ConnectorInputsTag = "connectorInputs" - def save(nbt: NBTTagCompound, forItem: Boolean): Unit = { + def saveData(nbt: CompoundNBT, forItem: Boolean): Unit = { nbt.setNewTagList(TriggersTag, triggers.map(t => { - val nbt = new NBTTagCompound() - nbt.setBoolean(IsActiveTag, t.isActive && !forItem) + val nbt = new CompoundNBT() + nbt.putBoolean(IsActiveTag, t.isActive && !forItem) nbt })) nbt.setNewTagList(ConnectorsTag, connectors.map(c => { - val nbt = new NBTTagCompound() - nbt.setIntArray(TriggerInputsTag, c.inputs.map(triggers.indexOf(_)).filter(_ >= 0).toArray) + val nbt = new CompoundNBT() + nbt.putIntArray(TriggerInputsTag, c.inputs.map(triggers.indexOf(_)).filter(_ >= 0).toArray) nbt })) nbt.setNewTagList(BehaviorsTag, behaviors.map(b => { - val nbt = new NBTTagCompound() - nbt.setIntArray(TriggerInputsTag, b.inputs.map(triggers.indexOf(_)).filter(_ >= 0).toArray) - nbt.setIntArray(ConnectorInputsTag, b.inputs.map(connectors.indexOf(_)).filter(_ >= 0).toArray) - nbt.setTag(BehaviorTag, b.provider.writeToNBT(b.behavior)) + val nbt = new CompoundNBT() + nbt.putIntArray(TriggerInputsTag, b.inputs.map(triggers.indexOf(_)).filter(_ >= 0).toArray) + nbt.putIntArray(ConnectorInputsTag, b.inputs.map(connectors.indexOf(_)).filter(_ >= 0).toArray) + nbt.put(BehaviorTag, b.provider.save(b.behavior)) nbt })) } - override def load(nbt: NBTTagCompound): Unit = { + override def loadData(nbt: CompoundNBT): Unit = { triggers.clear() - nbt.getTagList(TriggersTag, NBT.TAG_COMPOUND).foreach((t: NBTTagCompound) => { + nbt.getList(TriggersTag, NBT.TAG_COMPOUND).foreach((t: CompoundNBT) => { val neuron = new TriggerNeuron() neuron.isActive = t.getBoolean(IsActiveTag) triggers += neuron }) connectors.clear() - nbt.getTagList(ConnectorsTag, NBT.TAG_COMPOUND).foreach((t: NBTTagCompound) => { + nbt.getList(ConnectorsTag, NBT.TAG_COMPOUND).foreach((t: CompoundNBT) => { val neuron = new ConnectorNeuron() neuron.inputs ++= t.getIntArray(TriggerInputsTag).map(triggers.apply) connectors += neuron }) behaviors.clear() - nbt.getTagList(BehaviorsTag, NBT.TAG_COMPOUND).foreach((t: NBTTagCompound) => { - api.Nanomachines.getProviders.find(p => p.readFromNBT(controller.player, t.getCompoundTag(BehaviorTag)) match { + nbt.getList(BehaviorsTag, NBT.TAG_COMPOUND).foreach((t: CompoundNBT) => { + api.Nanomachines.getProviders.find(p => p.load(controller.player, t.getCompound(BehaviorTag)) match { case b: Behavior => val neuron = new BehaviorNeuron(p, b) neuron.inputs ++= t.getIntArray(TriggerInputsTag).map(triggers.apply) diff --git a/src/main/scala/li/cil/oc/common/nanomachines/provider/DisintegrationProvider.scala b/src/main/scala/li/cil/oc/common/nanomachines/provider/DisintegrationProvider.scala index 691d879d7c..7f93526519 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/provider/DisintegrationProvider.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/provider/DisintegrationProvider.scala @@ -9,33 +9,35 @@ import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP +import net.minecraft.block.BlockState +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.world.World +import net.minecraft.world.storage.IServerWorldInfo import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.event.entity.player.PlayerInteractEvent -import net.minecraftforge.fml.common.eventhandler.Event +import net.minecraftforge.eventbus.api.Event import scala.collection.mutable object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b1bddcdfe7") { - override def createScalaBehaviors(player: EntityPlayer) = Iterable(new DisintegrationBehavior(player)) + override def createScalaBehaviors(player: PlayerEntity) = Iterable(new DisintegrationBehavior(player)) - override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = new DisintegrationBehavior(player) + override def readBehaviorFromNBT(player: PlayerEntity, nbt: CompoundNBT) = new DisintegrationBehavior(player) - class DisintegrationBehavior(p: EntityPlayer) extends AbstractBehavior(p) { + class DisintegrationBehavior(p: PlayerEntity) extends AbstractBehavior(p) { var breakingMap = mutable.Map.empty[BlockPosition, SlowBreakInfo] var breakingMapNew = mutable.Map.empty[BlockPosition, SlowBreakInfo] // Note: intentionally not overriding getNameHint. Gotta find this one manually! override def onDisable(reason: DisableReason): Unit = { - val world = player.getEntityWorld + val world = player.level for (pos <- breakingMap.keys) { world.destroyBlockInWorldPartially(pos.hashCode(), pos, -1) } @@ -43,11 +45,11 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b } override def update(): Unit = { - val world = player.getEntityWorld - if (!world.isRemote) player match { + val world = player.level + if (!world.isClientSide) player match { case _: FakePlayer => // Nope - case playerMP: EntityPlayerMP => - val now = world.getTotalWorldTime + case playerMP: ServerPlayerEntity => + val now = world.getGameTime // Check blocks in range. val blockPos = BlockPosition(player) @@ -59,17 +61,21 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b breakingMapNew += pos -> info info.update(world, player, now) case None => - val event = new PlayerInteractEvent.LeftClickBlock(player, pos.toBlockPos, player.getHorizontalFacing, null) + val event = new PlayerInteractEvent.LeftClickBlock(player, pos.toBlockPos, player.getDirection) MinecraftForge.EVENT_BUS.post(event) val allowed = !event.isCanceled && event.getUseBlock != Event.Result.DENY && event.getUseItem != Event.Result.DENY - val adventureOk = !world.getWorldInfo.getGameType.hasLimitedInteractions || player.canPlayerEdit(pos.toBlockPos, null, player.getHeldItemMainhand) + val placingRestricted = world.getLevelData match { + case srvInfo: IServerWorldInfo => srvInfo.getGameType.isBlockPlacingRestricted + case _ => true // Means it's not a server world (somehow). + } + val adventureOk = !placingRestricted || player.mayUseItemAt(pos.toBlockPos, null, player.getItemInHand(Hand.MAIN_HAND)) if (allowed && adventureOk && !world.isAirBlock(pos)) { val blockState = world.getBlockState(pos.toBlockPos) - val hardness = blockState.getBlock.getPlayerRelativeBlockHardness(world.getBlockState(pos.toBlockPos), player, world, pos.toBlockPos) + val hardness = blockState.getDestroyProgress(player, world, pos.toBlockPos) if (hardness > 0) { val timeToBreak = (1 / hardness).toInt if (timeToBreak < 20 * 30) { - val info = new SlowBreakInfo(now, now + timeToBreak, pos, StackOption(player.getHeldItemMainhand).map(_.copy()), blockState) + val info = new SlowBreakInfo(now, now + timeToBreak, pos, StackOption(player.getItemInHand(Hand.MAIN_HAND)).map(_.copy()), blockState) world.destroyBlockInWorldPartially(pos.hashCode(), pos, 0) breakingMapNew += pos -> info } @@ -101,19 +107,19 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b } } - class SlowBreakInfo(val timeStarted: Long, val timeBroken: Long, val pos: BlockPosition, val originalTool: StackOption, val blockState: IBlockState) { + class SlowBreakInfo(val timeStarted: Long, val timeBroken: Long, val pos: BlockPosition, val originalTool: StackOption, val blockState: BlockState) { var lastDamageSent = 0 - def checkTool(player: EntityPlayer): Boolean = { - val currentTool = StackOption(player.getHeldItemMainhand).map(_.copy()) + def checkTool(player: PlayerEntity): Boolean = { + val currentTool = StackOption(player.getItemInHand(Hand.MAIN_HAND)).map(_.copy()) (currentTool, originalTool) match { - case (SomeStack(stackA), SomeStack(stackB)) => stackA.getItem == stackB.getItem && (stackA.isItemStackDamageable || stackA.getItemDamage == stackB.getItemDamage) + case (SomeStack(stackA), SomeStack(stackB)) => stackA.getItem == stackB.getItem && (stackA.isDamageableItem || stackA.getDamageValue == stackB.getDamageValue) case (EmptyStack, EmptyStack) => true case _ => false } } - def update(world: World, player: EntityPlayer, now: Long): Unit = { + def update(world: World, player: PlayerEntity, now: Long): Unit = { val timeTotal = timeBroken - timeStarted if (timeTotal > 0) { val timeTaken = now - timeStarted @@ -125,12 +131,12 @@ object DisintegrationProvider extends ScalaProvider("c4e7e3c2-8069-4fbb-b08e-74b } } - def finish(world: World, player: EntityPlayerMP): Unit = { + def finish(world: World, player: ServerPlayerEntity): Unit = { val sameBlock = world.getBlockState(pos.toBlockPos) == blockState if (sameBlock) { world.destroyBlockInWorldPartially(pos.hashCode(), pos, -1) - if (player.interactionManager.tryHarvestBlock(pos.toBlockPos)) { - world.playAuxSFX(2001, pos, Block.getIdFromBlock(blockState.getBlock) + (blockState.getBlock.getMetaFromState(blockState) << 12)) + if (player.gameMode.destroyBlock(pos.toBlockPos)) { + world.playAuxSFX(2001, pos, Block.getId(blockState)) } } } diff --git a/src/main/scala/li/cil/oc/common/nanomachines/provider/HungryProvider.scala b/src/main/scala/li/cil/oc/common/nanomachines/provider/HungryProvider.scala index 29a4bd2e18..4ff389a19f 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/provider/HungryProvider.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/provider/HungryProvider.scala @@ -6,24 +6,24 @@ import li.cil.oc.api.nanomachines.Behavior import li.cil.oc.api.nanomachines.DisableReason import li.cil.oc.api.prefab.AbstractBehavior import li.cil.oc.integration.util.DamageSourceWithRandomCause -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT object HungryProvider extends ScalaProvider("d697c24a-014c-4773-a288-23084a59e9e8") { final val FillCount = 10 // Create a bunch of these to have a higher chance of one being picked / available. final val HungryDamage = new DamageSourceWithRandomCause("oc.nanomachinesHungry", 3). - setDamageBypassesArmor(). - setDamageIsAbsolute() + bypassArmor(). + bypassMagic() - override def createScalaBehaviors(player: EntityPlayer): Iterable[Behavior] = Iterable.fill(FillCount)(new HungryBehavior(player)) + override def createScalaBehaviors(player: PlayerEntity): Iterable[Behavior] = Iterable.fill(FillCount)(new HungryBehavior(player)) - override protected def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound): Behavior = new HungryBehavior(player) + override protected def readBehaviorFromNBT(player: PlayerEntity, nbt: CompoundNBT): Behavior = new HungryBehavior(player) - class HungryBehavior(player: EntityPlayer) extends AbstractBehavior(player) { + class HungryBehavior(player: PlayerEntity) extends AbstractBehavior(player) { override def onDisable(reason: DisableReason): Unit = { if (reason == DisableReason.OutOfEnergy) { - player.attackEntityFrom(HungryDamage, Settings.get.nanomachinesHungryDamage) + player.hurt(HungryDamage, Settings.get.nanomachinesHungryDamage) api.Nanomachines.getController(player).changeBuffer(Settings.get.nanomachinesHungryEnergyRestored) } } diff --git a/src/main/scala/li/cil/oc/common/nanomachines/provider/MagnetProvider.scala b/src/main/scala/li/cil/oc/common/nanomachines/provider/MagnetProvider.scala index 49a0f966dd..6060551903 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/provider/MagnetProvider.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/provider/MagnetProvider.scala @@ -3,33 +3,33 @@ package li.cil.oc.common.nanomachines.provider import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.prefab.AbstractBehavior -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.math.Vec3d +import net.minecraft.entity.item.ItemEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.math.vector.Vector3d -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object MagnetProvider extends ScalaProvider("9324d5ec-71f1-41c2-b51c-406e527668fc") { - override def createScalaBehaviors(player: EntityPlayer) = Iterable(new MagnetBehavior(player)) + override def createScalaBehaviors(player: PlayerEntity) = Iterable(new MagnetBehavior(player)) - override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = new MagnetBehavior(player) + override def readBehaviorFromNBT(player: PlayerEntity, nbt: CompoundNBT) = new MagnetBehavior(player) - class MagnetBehavior(player: EntityPlayer) extends AbstractBehavior(player) { + class MagnetBehavior(player: PlayerEntity) extends AbstractBehavior(player) { override def getNameHint = "magnet" override def update(): Unit = { - val world = player.getEntityWorld - if (!world.isRemote) { + val world = player.level + if (!world.isClientSide) { val actualRange = Settings.get.nanomachineMagnetRange * api.Nanomachines.getController(player).getInputCount(this) - val items = world.getEntitiesWithinAABB(classOf[EntityItem], player.getEntityBoundingBox.grow(actualRange, actualRange, actualRange)) + val items = world.getEntitiesOfClass(classOf[ItemEntity], player.getBoundingBox.inflate(actualRange, actualRange, actualRange)) items.collect { - case item: EntityItem if !item.cannotPickup && !item.getItem.isEmpty && player.inventory.mainInventory.exists(stack => stack.isEmpty || stack.getCount < stack.getMaxStackSize && stack.isItemEqual(item.getItem)) => - val dx = player.posX - item.posX - val dy = player.posY - item.posY - val dz = player.posZ - item.posZ - val delta = new Vec3d(dx, dy, dz).normalize() - item.addVelocity(delta.x * 0.1, delta.y * 0.1, delta.z * 0.1) + case item: ItemEntity if !item.hasPickUpDelay && !item.getItem.isEmpty && player.inventory.items.exists(stack => stack.isEmpty || stack.getCount < stack.getMaxStackSize && stack.sameItem(item.getItem)) => + val dx = player.getX - item.getX + val dy = player.getY - item.getY + val dz = player.getZ - item.getZ + val delta = new Vector3d(dx, dy, dz).normalize() + item.push(delta.x * 0.1, delta.y * 0.1, delta.z * 0.1) } } } diff --git a/src/main/scala/li/cil/oc/common/nanomachines/provider/ParticleProvider.scala b/src/main/scala/li/cil/oc/common/nanomachines/provider/ParticleProvider.scala index 2aaa72b51c..2cad56597b 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/provider/ParticleProvider.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/provider/ParticleProvider.scala @@ -5,48 +5,50 @@ import li.cil.oc.api import li.cil.oc.api.nanomachines.Behavior import li.cil.oc.api.prefab.AbstractBehavior import li.cil.oc.util.PlayerUtils -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumParticleTypes +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.particles.BasicParticleType +import net.minecraft.particles.ParticleType +import net.minecraft.particles.ParticleTypes +import net.minecraftforge.registries.ForgeRegistries +import net.minecraftforge.registries.ForgeRegistry object ParticleProvider extends ScalaProvider("b48c4bbd-51bb-4915-9367-16cff3220e4b") { - final val ParticleTypes = Array( - EnumParticleTypes.FIREWORKS_SPARK, - EnumParticleTypes.TOWN_AURA, - EnumParticleTypes.SMOKE_NORMAL, - EnumParticleTypes.SPELL_WITCH, - EnumParticleTypes.NOTE, - EnumParticleTypes.ENCHANTMENT_TABLE, - EnumParticleTypes.FLAME, - EnumParticleTypes.LAVA, - EnumParticleTypes.WATER_SPLASH, - EnumParticleTypes.REDSTONE, - EnumParticleTypes.SLIME, - EnumParticleTypes.HEART, - EnumParticleTypes.VILLAGER_HAPPY + final val ParticleTypeList: Array[BasicParticleType] = Array( + ParticleTypes.FIREWORK, + ParticleTypes.SMOKE, + ParticleTypes.WITCH, + ParticleTypes.NOTE, + ParticleTypes.ENCHANT, + ParticleTypes.FLAME, + ParticleTypes.LAVA, + ParticleTypes.SPLASH, + ParticleTypes.ITEM_SLIME, + ParticleTypes.HEART, + ParticleTypes.HAPPY_VILLAGER ) - override def createScalaBehaviors(player: EntityPlayer): Iterable[Behavior] = ParticleTypes.map(new ParticleBehavior(_, player)) + override def createScalaBehaviors(player: PlayerEntity): Iterable[Behavior] = ParticleTypeList.map(new ParticleBehavior(_, player)) - override def writeBehaviorToNBT(behavior: Behavior, nbt: NBTTagCompound): Unit = { + override def writeBehaviorToNBT(behavior: Behavior, nbt: CompoundNBT): Unit = { behavior match { case particles: ParticleBehavior => - nbt.setInteger("effectName", particles.effectType.getParticleID) + nbt.putInt("effectName", ForgeRegistries.PARTICLE_TYPES.asInstanceOf[ForgeRegistry[ParticleType[_]]].getID(particles.effectType)) case _ => // Wat. } } - override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound): Behavior = { - val effectType = EnumParticleTypes.getParticleFromId(nbt.getInteger("effectName")) - new ParticleBehavior(effectType, player) + override def readBehaviorFromNBT(player: PlayerEntity, nbt: CompoundNBT): Behavior = { + val effectType = ForgeRegistries.PARTICLE_TYPES.asInstanceOf[ForgeRegistry[ParticleType[_]]].getValue(nbt.getInt("effectName")) + new ParticleBehavior(effectType.asInstanceOf[BasicParticleType], player) } - class ParticleBehavior(var effectType: EnumParticleTypes, player: EntityPlayer) extends AbstractBehavior(player) { - override def getNameHint = "particles." + effectType.getParticleName + class ParticleBehavior(var effectType: BasicParticleType, player: PlayerEntity) extends AbstractBehavior(player) { + override def getNameHint = "particles." + effectType.getRegistryName.getPath override def update(): Unit = { - val world = player.getEntityWorld - if (world.isRemote && Settings.get.enableNanomachinePfx) { + val world = player.level + if (world.isClientSide && Settings.get.enableNanomachinePfx) { PlayerUtils.spawnParticleAround(player, effectType, api.Nanomachines.getController(player).getInputCount(this) * 0.25) } } diff --git a/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala b/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala index 548d1751b2..987c341541 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/provider/PotionProvider.scala @@ -5,12 +5,14 @@ import li.cil.oc.api import li.cil.oc.api.nanomachines.Behavior import li.cil.oc.api.nanomachines.DisableReason import li.cil.oc.api.prefab.AbstractBehavior -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.potion.Potion -import net.minecraft.potion.PotionEffect +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.potion.Effect +import net.minecraft.potion.EffectInstance +import net.minecraft.util.ResourceLocation +import net.minecraftforge.registries.ForgeRegistries -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object PotionProvider extends ScalaProvider("c29e4eec-5a46-479a-9b3d-ad0f06da784a") { // Lazy to give other mods a chance to register their potions. @@ -18,46 +20,47 @@ object PotionProvider extends ScalaProvider("c29e4eec-5a46-479a-9b3d-ad0f06da784 def filterPotions[T](list: Iterable[T]) = { list.map { - case name: String => Option(Potion.getPotionFromResourceLocation(name)) - case id: java.lang.Number => Option(Potion.getPotionById(id.intValue())) + case name: String => Option(ForgeRegistries.POTIONS.getValue(new ResourceLocation(name))) + case loc: ResourceLocation => Option(ForgeRegistries.POTIONS.getValue(loc)) + case id: java.lang.Number => Option(Effect.byId(id.intValue())) case _ => None }.collect { case Some(potion) => potion }.toSet } - def isPotionEligible(potion: Potion) = potion != null && PotionWhitelist.contains(potion) + def isPotionEligible(potion: Effect) = potion != null && PotionWhitelist.contains(potion) - override def createScalaBehaviors(player: EntityPlayer) = { - Potion.REGISTRY.filter(isPotionEligible).map(new PotionBehavior(_, player)) + override def createScalaBehaviors(player: PlayerEntity) = { + ForgeRegistries.POTIONS.getValues.filter(isPotionEligible).map(new PotionBehavior(_, player)) } - override def writeBehaviorToNBT(behavior: Behavior, nbt: NBTTagCompound): Unit = { + override def writeBehaviorToNBT(behavior: Behavior, nbt: CompoundNBT): Unit = { behavior match { case potionBehavior: PotionBehavior => - nbt.setString("potionId", Potion.REGISTRY.getNameForObject(potionBehavior.potion).toString) + nbt.putString("potionId", potionBehavior.potion.getRegistryName.toString) case _ => // Shouldn't happen, ever. } } - override def readBehaviorFromNBT(player: EntityPlayer, nbt: NBTTagCompound) = { + override def readBehaviorFromNBT(player: PlayerEntity, nbt: CompoundNBT) = { val potionId = nbt.getString("potionId") - new PotionBehavior(Potion.getPotionFromResourceLocation(potionId), player) + new PotionBehavior(ForgeRegistries.POTIONS.getValue(new ResourceLocation(potionId)), player) } - class PotionBehavior(val potion: Potion, player: EntityPlayer) extends AbstractBehavior(player) { + class PotionBehavior(val potion: Effect, player: PlayerEntity) extends AbstractBehavior(player) { final val Duration = 600 - def amplifier(player: EntityPlayer) = api.Nanomachines.getController(player).getInputCount(this) - 1 + def amplifier(player: PlayerEntity) = api.Nanomachines.getController(player).getInputCount(this) - 1 - override def getNameHint: String = potion.getName.stripPrefix("potion.") + override def getNameHint: String = potion.getDescriptionId.stripPrefix("effect.") override def onDisable(reason: DisableReason): Unit = { - player.removePotionEffect(potion) + player.removeEffect(potion) } override def update(): Unit = { - player.addPotionEffect(new PotionEffect(potion, Duration, amplifier(player), true, Settings.get.enableNanomachinePfx)) + player.addEffect(new EffectInstance(potion, Duration, amplifier(player), true, Settings.get.enableNanomachinePfx)) } } diff --git a/src/main/scala/li/cil/oc/common/nanomachines/provider/ScalaProvider.scala b/src/main/scala/li/cil/oc/common/nanomachines/provider/ScalaProvider.scala index 93285282a4..849b763b78 100644 --- a/src/main/scala/li/cil/oc/common/nanomachines/provider/ScalaProvider.scala +++ b/src/main/scala/li/cil/oc/common/nanomachines/provider/ScalaProvider.scala @@ -2,12 +2,13 @@ package li.cil.oc.common.nanomachines.provider import li.cil.oc.api.nanomachines.Behavior import li.cil.oc.api.prefab.AbstractProvider -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ abstract class ScalaProvider(id: String) extends AbstractProvider(id) { - def createScalaBehaviors(player: EntityPlayer): Iterable[Behavior] + def createScalaBehaviors(player: PlayerEntity): Iterable[Behavior] - override def createBehaviors(player: EntityPlayer): java.lang.Iterable[Behavior] = asJavaIterable(createScalaBehaviors(player)) + override def createBehaviors(player: PlayerEntity): java.lang.Iterable[Behavior] = asJavaIterable(createScalaBehaviors(player)) } diff --git a/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala index a746a58d71..b5c1fc05df 100644 --- a/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala @@ -3,38 +3,35 @@ package li.cil.oc.common.recipe import li.cil.oc.util.Color import li.cil.oc.util.ItemColorizer import li.cil.oc.util.StackOption -import net.minecraft.block.Block -import net.minecraft.inventory.InventoryCrafting +import net.minecraft.inventory.CraftingInventory +import net.minecraft.item.crafting.SpecialRecipe import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.util.IItemProvider +import net.minecraft.util.ResourceLocation import net.minecraft.world.World /** * @author asie, Vexatos */ -class ColorizeRecipe(target: Item, source: Array[Item] = null) extends ContainerItemAwareRecipe { - def this(target: Block, source: Array[Item]) = this(Item.getItemFromBlock(target), source) - def this(target: Block) = this(target, null) +class ColorizeRecipe(id: ResourceLocation, target: IItemProvider) extends SpecialRecipe(id) { + val targetItem: Item = target.asItem() - val targetItem: Item = target - val sourceItems: Array[Item] = if (source != null) source else Array(targetItem) - - override def matches(crafting: InventoryCrafting, world: World): Boolean = { - val stacks = (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i))) - val targets = stacks.filter(stack => sourceItems.contains(stack.getItem) || stack.getItem == targetItem) + override def matches(crafting: CraftingInventory, world: World): Boolean = { + val stacks = (0 until crafting.getContainerSize).flatMap(i => StackOption(crafting.getItem(i))) + val targets = stacks.filter(stack => stack.getItem == targetItem) val other = stacks.filterNot(targets.contains(_)) targets.size == 1 && other.nonEmpty && other.forall(Color.isDye) } - override def getCraftingResult(crafting: InventoryCrafting): ItemStack = { + override def assemble(crafting: CraftingInventory): ItemStack = { var targetStack: ItemStack = ItemStack.EMPTY val color = Array[Int](0, 0, 0) var colorCount = 0 var maximum = 0 - (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i))).foreach { stack => - if (sourceItems.contains(stack.getItem) - || stack.getItem == targetItem) { + (0 until crafting.getContainerSize).flatMap(i => StackOption(crafting.getItem(i))).foreach { stack => + if (stack.getItem == targetItem) { targetStack = stack.copy() targetStack.setCount(1) } else { @@ -42,7 +39,7 @@ class ColorizeRecipe(target: Item, source: Array[Item] = null) extends Container if (dye.isEmpty) return ItemStack.EMPTY - val itemColor = Color.byOreName(dye.get).getColorComponentValues + val itemColor = Color.byTag(dye.get).getTextureDiffuseColors val red = (itemColor(0) * 255.0F).toInt val green = (itemColor(1) * 255.0F).toInt val blue = (itemColor(2) * 255.0F).toInt @@ -68,8 +65,6 @@ class ColorizeRecipe(target: Item, source: Array[Item] = null) extends Container color(2) = (color(2).toFloat + blue * 255.0F).toInt colorCount = colorCount + 1 } - } else if (sourceItems.contains(targetStack.getItem)) { - targetStack = new ItemStack(targetItem, targetStack.getCount, targetStack.getItemDamage) } var red = color(0) / colorCount @@ -84,7 +79,7 @@ class ColorizeRecipe(target: Item, source: Array[Item] = null) extends Container targetStack } - override def getMinimumRecipeSize = 2 + override def canCraftInDimensions(width: Int, height: Int): Boolean = width * height >= 2 - override def getRecipeOutput = ItemStack.EMPTY + override def getSerializer = RecipeSerializers.CRAFTING_COLORIZE } diff --git a/src/main/scala/li/cil/oc/common/recipe/ContainerItemAwareRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ContainerItemAwareRecipe.scala deleted file mode 100644 index 69f38488ba..0000000000 --- a/src/main/scala/li/cil/oc/common/recipe/ContainerItemAwareRecipe.scala +++ /dev/null @@ -1,14 +0,0 @@ -package li.cil.oc.common.recipe - -import net.minecraft.inventory.InventoryCrafting -import net.minecraft.item.crafting.IRecipe -import net.minecraftforge.common.ForgeHooks -import net.minecraftforge.registries.IForgeRegistryEntry - -trait ContainerItemAwareRecipe extends IForgeRegistryEntry.Impl[IRecipe] with IRecipe { - override def getRemainingItems(inv: InventoryCrafting) = ForgeHooks.defaultRecipeGetRemainingItems(inv) - - def getMinimumRecipeSize: Int - - override def canFit(width: Int, height: Int): Boolean = width * height >= getMinimumRecipeSize -} diff --git a/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala index 7ec676235e..0486b98b49 100644 --- a/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/DecolorizeRecipe.scala @@ -3,31 +3,32 @@ package li.cil.oc.common.recipe import li.cil.oc.util.ItemColorizer import li.cil.oc.util.StackOption import net.minecraft.block.Block -import net.minecraft.init.Items -import net.minecraft.inventory.InventoryCrafting +import net.minecraft.inventory.CraftingInventory +import net.minecraft.item.crafting.SpecialRecipe import net.minecraft.item.Item +import net.minecraft.item.Items import net.minecraft.item.ItemStack +import net.minecraft.util.IItemProvider +import net.minecraft.util.ResourceLocation import net.minecraft.world.World /** * @author Vexatos */ -class DecolorizeRecipe(target: Item) extends ContainerItemAwareRecipe { - def this(target: Block) = this(Item.getItemFromBlock(target)) +class DecolorizeRecipe(id: ResourceLocation, target: IItemProvider) extends SpecialRecipe(id) { + val targetItem: Item = target.asItem() - val targetItem: Item = target - - override def matches(crafting: InventoryCrafting, world: World): Boolean = { - val stacks = (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i))) + override def matches(crafting: CraftingInventory, world: World): Boolean = { + val stacks = (0 until crafting.getContainerSize).flatMap(i => StackOption(crafting.getItem(i))) val targets = stacks.filter(stack => stack.getItem == targetItem) val other = stacks.filterNot(targets.contains) targets.size == 1 && other.size == 1 && other.forall(_.getItem == Items.WATER_BUCKET) } - override def getCraftingResult(crafting: InventoryCrafting): ItemStack = { + override def assemble(crafting: CraftingInventory): ItemStack = { var targetStack: ItemStack = ItemStack.EMPTY - (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i))).foreach { stack => + (0 until crafting.getContainerSize).flatMap(i => StackOption(crafting.getItem(i))).foreach { stack => if (stack.getItem == targetItem) { targetStack = stack.copy() targetStack.setCount(1) @@ -42,7 +43,7 @@ class DecolorizeRecipe(target: Item) extends ContainerItemAwareRecipe { targetStack } - override def getMinimumRecipeSize = 2 + override def canCraftInDimensions(width: Int, height: Int): Boolean = width * height >= 2 - override def getRecipeOutput = ItemStack.EMPTY + override def getSerializer = RecipeSerializers.CRAFTING_DECOLORIZE } diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedFuzzyShapelessRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedFuzzyShapelessRecipe.scala deleted file mode 100644 index 6232b9e577..0000000000 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedFuzzyShapelessRecipe.scala +++ /dev/null @@ -1,27 +0,0 @@ -package li.cil.oc.common.recipe - -import net.minecraft.inventory.InventoryCrafting -import net.minecraft.item.ItemStack -import net.minecraftforge.oredict.ShapelessOreRecipe - -import scala.collection.mutable.ListBuffer - -class ExtendedFuzzyShapelessRecipe(result: ItemStack, ingredients: AnyRef*) extends ExtendedShapelessOreRecipe(result, ingredients: _*) { - override def matches(inv: net.minecraft.inventory.InventoryCrafting, world: net.minecraft.world.World): Boolean = { - val requiredItems = ingredients.map(any => any.asInstanceOf[ItemStack]).toList.to[ListBuffer] - //.groupBy{ case s: ItemStack => s.getItem }.mapValues(_.size).toSeq: _*) - for (i <- 0 until inv.getSizeInventory) { - val itemStack = inv.getStackInSlot(i) - if (!itemStack.isEmpty) { - val index = requiredItems.indexWhere(req => { - if (req.getItem != itemStack.getItem) return false - req.getItemDamage == itemStack.getItemDamage - }) - if (index >= 0) { - requiredItems.remove(index) - } - } - } - requiredItems.isEmpty - } -} diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala index 46bec34d3f..328d760fb4 100644 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedRecipe.scala @@ -12,16 +12,18 @@ import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.item.data.RobotData import li.cil.oc.common.item.data.TabletData import li.cil.oc.server.machine.luac.LuaStateFactory -import li.cil.oc.util.Color import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.SideTracker -import net.minecraft.init.Blocks -import net.minecraft.inventory.InventoryCrafting +import net.minecraft.block.Blocks +import net.minecraft.inventory.CraftingInventory +import net.minecraft.item.DyeColor +import net.minecraft.item.Items import net.minecraft.item.ItemStack import net.minecraft.item.crafting.IRecipe -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tags.ItemTags -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.util.control.Breaks._ object ExtendedRecipe { @@ -47,24 +49,18 @@ object ExtendedRecipe { private lazy val robot = api.Items.get(Constants.BlockName.Robot) private lazy val tablet = api.Items.get(Constants.ItemName.Tablet) private lazy val print = api.Items.get(Constants.BlockName.Print) - private lazy val disabled = { - val stack = new ItemStack(Blocks.DIRT) - val tag = new NBTTagCompound() - tag.setNewCompoundTag("display", _.setNewTagList("Lore", "Autocrafting of this item is disabled to avoid exploits.")) - stack.setTagCompound(tag) - stack - } + private val beaconBlocks = ItemTags.bind("forge:beacon_base_blocks") - def addNBTToResult(recipe: IRecipe, craftedStack: ItemStack, inventory: InventoryCrafting): ItemStack = { + def addNBTToResult(recipe: IRecipe[_], craftedStack: ItemStack, inventory: CraftingInventory): ItemStack = { val craftedItemName = api.Items.get(craftedStack) if (craftedItemName == navigationUpgrade) { Option(api.Driver.driverFor(craftedStack)).foreach(driver => for (stack <- getItems(inventory)) { - if (stack.getItem == net.minecraft.init.Items.FILLED_MAP) { + if (stack.getItem == Items.FILLED_MAP) { // Store information of the map used for crafting in the result. val nbt = driver.dataTag(craftedStack) - nbt.setNewCompoundTag(Settings.namespace + "map", stack.writeToNBT) + nbt.setNewCompoundTag(Settings.namespace + "map", stack.save) } }) } @@ -73,7 +69,7 @@ object ExtendedRecipe { if (SideTracker.isServer) { Option(api.Driver.driverFor(craftedStack)).foreach(driver => { val nbt = driver.dataTag(craftedStack) - nbt.setString(Settings.namespace + "tunnel", UUID.randomUUID().toString) + nbt.putString(Settings.namespace + "tunnel", UUID.randomUUID().toString) }) } } @@ -83,32 +79,29 @@ object ExtendedRecipe { } if (craftedItemName == floppy || hdds.contains(craftedItemName)) { - if (!craftedStack.hasTagCompound) { - craftedStack.setTagCompound(new NBTTagCompound()) - } - val nbt = craftedStack.getTagCompound - if (recipe.canFit(1, 1)) { + val nbt = craftedStack.getOrCreateTag + if (recipe.canCraftInDimensions(1, 1)) { // Formatting / loot to normal disk conversion, only keep coloring. val colorKey = Settings.namespace + "color" for (stack <- getItems(inventory)) { - if (api.Items.get(stack) != null && (api.Items.get(stack) == floppy || api.Items.get(stack).name == "lootDisk") && stack.hasTagCompound) { - val oldData = stack.getTagCompound - if (oldData.hasKey(colorKey) && oldData.getInteger(colorKey) != Color.dyes.indexOf("lightGray")) { - nbt.setTag(colorKey, oldData.getTag(colorKey).copy()) + if (api.Items.get(stack) != null && (api.Items.get(stack) == floppy || api.Items.get(stack).name == "lootDisk") && stack.hasTag) { + val oldData = stack.getTag + if (oldData.contains(colorKey) && oldData.getInt(colorKey) != DyeColor.LIGHT_GRAY.getId) { + nbt.put(colorKey, oldData.get(colorKey).copy()) } } } - if (nbt.hasNoTags) { - craftedStack.setTagCompound(null) + if (nbt.isEmpty) { + craftedStack.setTag(null) } } else if (getItems(inventory).forall(api.Items.get(_) == floppy)) { // Copy operation. for (stack <- getItems(inventory)) { - if (api.Items.get(stack) == floppy && stack.hasTagCompound) { - val oldData = stack.getTagCompound - for (oldTagName <- oldData.getKeySet.map(_.asInstanceOf[String]) if !nbt.hasKey(oldTagName)) { - nbt.setTag(oldTagName, oldData.getTag(oldTagName).copy()) + if (api.Items.get(stack) == floppy && stack.hasTag) { + val oldData = stack.getTag + for (oldTagName <- oldData.getAllKeys.map(_.asInstanceOf[String]) if !nbt.contains(oldTagName)) { + nbt.put(oldTagName, oldData.get(oldTagName).copy()) } } } @@ -116,43 +109,35 @@ object ExtendedRecipe { } if (craftedItemName == print && - recipe.isInstanceOf[ExtendedShapelessOreRecipe] && - recipe.asInstanceOf[ExtendedShapelessOreRecipe].getIngredients.size == 2) { + recipe.getIngredients.size == 2) { // First, copy old data. val data = new PrintData(craftedStack) val inputs = getItems(inventory) for (stack <- inputs) { if (api.Items.get(stack) == print) { - data.load(stack) + data.loadData(stack) } } // Then apply new data. - val beaconBlocks = Array( - new ItemStack(net.minecraft.init.Blocks.IRON_BLOCK), - new ItemStack(net.minecraft.init.Blocks.GOLD_BLOCK), - new ItemStack(net.minecraft.init.Blocks.EMERALD_BLOCK), - new ItemStack(net.minecraft.init.Blocks.DIAMOND_BLOCK) - ) - - val glowstoneDust = new ItemStack(net.minecraft.init.Items.GLOWSTONE_DUST) - val glowstone = new ItemStack(net.minecraft.init.Blocks.GLOWSTONE) + val glowstoneDust = new ItemStack(Items.GLOWSTONE_DUST) + val glowstone = new ItemStack(Blocks.GLOWSTONE) for (stack <- inputs) { - if (beaconBlocks.exists(_.isItemEqual(stack))) { + if (stack.getItem.is(beaconBlocks)) { if (data.isBeaconBase) { // Crafting wouldn't change anything, prevent accidental resource loss. return ItemStack.EMPTY } data.isBeaconBase = true } - if (glowstoneDust.isItemEqual(stack)) { + if (glowstoneDust.sameItem(stack)) { if (data.lightLevel == 15) { // Crafting wouldn't change anything, prevent accidental resource loss. return ItemStack.EMPTY } data.lightLevel = math.min(15, data.lightLevel + 1) } - if (glowstone.isItemEqual(stack)) { + if (glowstone.sameItem(stack)) { if (data.lightLevel == 15) { // Crafting wouldn't change anything, prevent accidental resource loss. return ItemStack.EMPTY @@ -162,20 +147,19 @@ object ExtendedRecipe { } // Finally apply modified data. - data.save(craftedStack) + data.saveData(craftedStack) } // EEPROM copying. if (craftedItemName == eeprom && craftedStack.getCount == 2 && - recipe.isInstanceOf[ExtendedShapelessOreRecipe] && - recipe.asInstanceOf[ExtendedShapelessOreRecipe].getIngredients.size == 2) breakable { + recipe.getIngredients.size == 2) breakable { for (stack <- getItems(inventory)) { - if (api.Items.get(stack) == eeprom && stack.hasTagCompound) { - val copy = stack.getTagCompound.copy.asInstanceOf[NBTTagCompound] + if (api.Items.get(stack) == eeprom && stack.hasTag) { + val copy = stack.getTag.copy.asInstanceOf[CompoundNBT] // Erase node address, just in case. - copy.getCompoundTag(Settings.namespace + "data").getCompoundTag("node").removeTag("address") - craftedStack.setTagCompound(copy) + copy.getCompound(Settings.namespace + "data").getCompound("node").remove("address") + craftedStack.setTag(copy) break() } } @@ -190,9 +174,9 @@ object ExtendedRecipe { craftedStack } - private def getItems(inventory: InventoryCrafting) = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot).filter(!_.isEmpty) + private def getItems(inventory: CraftingInventory) = (0 until inventory.getContainerSize).map(inventory.getItem).filter(!_.isEmpty) - private def recraft(craftedStack: ItemStack, inventory: InventoryCrafting, descriptor: ItemInfo, dataFactory: (ItemStack) => ItemDataWrapper) { + private def recraft(craftedStack: ItemStack, inventory: CraftingInventory, descriptor: ItemInfo, dataFactory: (ItemStack) => ItemDataWrapper) { if (api.Items.get(craftedStack) == descriptor) { // Find old Microcontroller. getItems(inventory).find(api.Items.get(_) == descriptor) match { @@ -206,7 +190,7 @@ object ExtendedRecipe { // Insert new EEPROM. for (stack <- getItems(inventory)) { if (api.Items.get(stack) == eeprom) { - data.components :+= stack.copy.splitStack(1) + data.components :+= stack.copy.split(1) } } @@ -231,7 +215,7 @@ object ExtendedRecipe { override def components_=(value: Array[ItemStack]): Unit = data.components = value - override def save(stack: ItemStack): Unit = data.save(stack) + override def save(stack: ItemStack): Unit = data.saveData(stack) } private class DroneDataWrapper(val stack: ItemStack) extends ItemDataWrapper { @@ -241,7 +225,7 @@ object ExtendedRecipe { override def components_=(value: Array[ItemStack]): Unit = data.components = value - override def save(stack: ItemStack): Unit = data.save(stack) + override def save(stack: ItemStack): Unit = data.saveData(stack) } private class RobotDataWrapper(val stack: ItemStack) extends ItemDataWrapper { @@ -251,7 +235,7 @@ object ExtendedRecipe { override def components_=(value: Array[ItemStack]): Unit = data.components = value - override def save(stack: ItemStack): Unit = data.save(stack) + override def save(stack: ItemStack): Unit = data.saveData(stack) } private class TabletDataWrapper(val stack: ItemStack) extends ItemDataWrapper { @@ -261,7 +245,7 @@ object ExtendedRecipe { override def save(stack: ItemStack): Unit = { data.items = components.clone() - data.save(stack) + data.saveData(stack) } } diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedOreRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedOreRecipe.scala deleted file mode 100644 index 0dc472b3e0..0000000000 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedOreRecipe.scala +++ /dev/null @@ -1,11 +0,0 @@ -package li.cil.oc.common.recipe - -import net.minecraft.inventory.InventoryCrafting -import net.minecraft.item.ItemStack -import net.minecraft.util.ResourceLocation -import net.minecraftforge.oredict.ShapedOreRecipe - -class ExtendedShapedOreRecipe(result: ItemStack, ingredients: AnyRef*) extends ShapedOreRecipe(null, result, ingredients: _*) { - override def getCraftingResult(inventory: InventoryCrafting) = - ExtendedRecipe.addNBTToResult(this, super.getCraftingResult(inventory), inventory) -} diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedRecipe.java b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedRecipe.java new file mode 100644 index 0000000000..cd0af03135 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapedRecipe.java @@ -0,0 +1,101 @@ +package li.cil.oc.common.recipe; + +import com.google.gson.JsonObject; +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.ICraftingRecipe; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.item.crafting.ShapedRecipe; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.common.crafting.IShapedRecipe; +import net.minecraftforge.registries.ForgeRegistryEntry; + +public class ExtendedShapedRecipe implements ICraftingRecipe, IShapedRecipe { + private ShapedRecipe wrapped; + + public ExtendedShapedRecipe(ShapedRecipe wrapped) { + this.wrapped = wrapped; + } + + @Override + public boolean matches(CraftingInventory inv, World world) { + return wrapped.matches(inv, world); + } + + @Override + public ItemStack assemble(CraftingInventory inv) { + return ExtendedRecipe.addNBTToResult(this, wrapped.assemble(inv), inv); + } + + @Override + public boolean canCraftInDimensions(int w, int h) { + return wrapped.canCraftInDimensions(w, h); + } + + @Override + public ItemStack getResultItem() { + return wrapped.getResultItem(); + } + + @Override + public NonNullList getRemainingItems(CraftingInventory inv) { + return wrapped.getRemainingItems(inv); + } + + @Override + public NonNullList getIngredients() { + return wrapped.getIngredients(); + } + + @Override + public ResourceLocation getId() { + return wrapped.getId(); + } + + @Override + public IRecipeSerializer getSerializer() { + return RecipeSerializers.CRAFTING_SHAPED_EXTENDED; + } + + @Override + public String getGroup() { + return wrapped.getGroup(); + } + + @Override + public int getRecipeWidth() { + return wrapped.getRecipeWidth(); + } + + @Override + public int getRecipeHeight() { + return wrapped.getRecipeHeight(); + } + + public static final class Serializer extends ForgeRegistryEntry> + implements IRecipeSerializer { + + @Override + public ExtendedShapedRecipe fromJson(ResourceLocation recipeId, JsonObject json) { + ShapedRecipe wrapped = IRecipeSerializer.SHAPED_RECIPE.fromJson(recipeId, json); + return new ExtendedShapedRecipe(wrapped); + } + + @Override + public ExtendedShapedRecipe fromNetwork(ResourceLocation recipeId, PacketBuffer buff) { + ShapedRecipe wrapped = IRecipeSerializer.SHAPED_RECIPE.fromNetwork(recipeId, buff); + return new ExtendedShapedRecipe(wrapped); + } + + @Override + public void toNetwork(PacketBuffer buff, ExtendedShapedRecipe recipe) { + IRecipeSerializer serializer = + (IRecipeSerializer) recipe.wrapped.getSerializer(); + serializer.toNetwork(buff, recipe.wrapped); + } + } +} diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessOreRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessOreRecipe.scala deleted file mode 100644 index 1c9c9ce6b2..0000000000 --- a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessOreRecipe.scala +++ /dev/null @@ -1,10 +0,0 @@ -package li.cil.oc.common.recipe - -import net.minecraft.inventory.InventoryCrafting -import net.minecraft.item.ItemStack -import net.minecraftforge.oredict.ShapelessOreRecipe - -class ExtendedShapelessOreRecipe(result: ItemStack, ingredients: AnyRef*) extends ShapelessOreRecipe(null, result, ingredients: _*) { - override def getCraftingResult(inventory: InventoryCrafting): ItemStack = - ExtendedRecipe.addNBTToResult(this, super.getCraftingResult(inventory), inventory) -} diff --git a/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessRecipe.java b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessRecipe.java new file mode 100644 index 0000000000..be68905ded --- /dev/null +++ b/src/main/scala/li/cil/oc/common/recipe/ExtendedShapelessRecipe.java @@ -0,0 +1,90 @@ +package li.cil.oc.common.recipe; + +import com.google.gson.JsonObject; +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.ICraftingRecipe; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.item.crafting.ShapelessRecipe; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.registries.ForgeRegistryEntry; + +public class ExtendedShapelessRecipe implements ICraftingRecipe { + private ShapelessRecipe wrapped; + + public ExtendedShapelessRecipe(ShapelessRecipe wrapped) { + this.wrapped = wrapped; + } + + @Override + public boolean matches(CraftingInventory inv, World world) { + return wrapped.matches(inv, world); + } + + @Override + public ItemStack assemble(CraftingInventory inv) { + return ExtendedRecipe.addNBTToResult(this, wrapped.assemble(inv), inv); + } + + @Override + public boolean canCraftInDimensions(int w, int h) { + return wrapped.canCraftInDimensions(w, h); + } + + @Override + public ItemStack getResultItem() { + return wrapped.getResultItem(); + } + + @Override + public NonNullList getRemainingItems(CraftingInventory inv) { + return wrapped.getRemainingItems(inv); + } + + @Override + public NonNullList getIngredients() { + return wrapped.getIngredients(); + } + + @Override + public ResourceLocation getId() { + return wrapped.getId(); + } + + @Override + public IRecipeSerializer getSerializer() { + return RecipeSerializers.CRAFTING_SHAPELESS_EXTENDED; + } + + @Override + public String getGroup() { + return wrapped.getGroup(); + } + + public static final class Serializer extends ForgeRegistryEntry> + implements IRecipeSerializer { + + @Override + public ExtendedShapelessRecipe fromJson(ResourceLocation recipeId, JsonObject json) { + ShapelessRecipe wrapped = IRecipeSerializer.SHAPELESS_RECIPE.fromJson(recipeId, json); + return new ExtendedShapelessRecipe(wrapped); + } + + @Override + public ExtendedShapelessRecipe fromNetwork(ResourceLocation recipeId, PacketBuffer buff) { + ShapelessRecipe wrapped = IRecipeSerializer.SHAPELESS_RECIPE.fromNetwork(recipeId, buff); + return new ExtendedShapelessRecipe(wrapped); + } + + @Override + public void toNetwork(PacketBuffer buff, ExtendedShapelessRecipe recipe) { + IRecipeSerializer serializer = + (IRecipeSerializer) recipe.wrapped.getSerializer(); + serializer.toNetwork(buff, recipe.wrapped); + } + } +} diff --git a/src/main/scala/li/cil/oc/common/recipe/ItemSpecialSerializer.java b/src/main/scala/li/cil/oc/common/recipe/ItemSpecialSerializer.java new file mode 100644 index 0000000000..ec4e1335b6 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/recipe/ItemSpecialSerializer.java @@ -0,0 +1,47 @@ +package li.cil.oc.common.recipe; + +import java.util.function.BiFunction; +import java.util.function.Function; + +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import net.minecraft.item.Item; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.IItemProvider; +import net.minecraft.util.JSONUtils; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.ForgeRegistryEntry; + +public class ItemSpecialSerializer> extends ForgeRegistryEntry> + implements IRecipeSerializer { + + private BiFunction ctor; + private Function getter; + + public ItemSpecialSerializer(BiFunction ctor, Function getter) { + this.ctor = ctor; + this.getter = getter; + } + + @Override + public T fromJson(ResourceLocation recipeId, JsonObject json) { + ResourceLocation loc = new ResourceLocation(JSONUtils.getAsString(json, "item")); + if (!ForgeRegistries.ITEMS.containsKey(loc)) { + throw new JsonSyntaxException("Unknown item '" + loc + "'"); + } + return ctor.apply(recipeId, ForgeRegistries.ITEMS.getValue(loc)); + } + + @Override + public T fromNetwork(ResourceLocation recipeId, PacketBuffer buff) { + return ctor.apply(recipeId, buff.readRegistryIdUnsafe(ForgeRegistries.ITEMS)); + } + + @Override + public void toNetwork(PacketBuffer buff, T recipe) { + buff.writeRegistryIdUnsafe(ForgeRegistries.ITEMS, getter.apply(recipe)); + } +} diff --git a/src/main/scala/li/cil/oc/common/recipe/LootDiskCyclingRecipe.scala b/src/main/scala/li/cil/oc/common/recipe/LootDiskCyclingRecipe.scala index 2743649551..0116ac06a0 100644 --- a/src/main/scala/li/cil/oc/common/recipe/LootDiskCyclingRecipe.scala +++ b/src/main/scala/li/cil/oc/common/recipe/LootDiskCyclingRecipe.scala @@ -1,25 +1,33 @@ package li.cil.oc.common.recipe +import li.cil.oc.Constants import li.cil.oc.Settings +import li.cil.oc.api import li.cil.oc.common.Loot import li.cil.oc.integration.util.Wrench import li.cil.oc.util.StackOption -import net.minecraft.inventory.InventoryCrafting +import net.minecraft.inventory.CraftingInventory import net.minecraft.item.ItemStack -import net.minecraft.item.crafting.IRecipe +import net.minecraft.item.crafting.Ingredient +import net.minecraft.item.crafting.ICraftingRecipe import net.minecraft.util.NonNullList +import net.minecraft.util.ResourceLocation import net.minecraft.world.World -import net.minecraftforge.registries.IForgeRegistryEntry +import scala.collection.JavaConverters import scala.collection.immutable -class LootDiskCyclingRecipe extends IForgeRegistryEntry.Impl[IRecipe] with IRecipe { - override def matches(crafting: InventoryCrafting, world: World): Boolean = { +class LootDiskCyclingRecipe(val getId: ResourceLocation) extends ICraftingRecipe { + val ingredients = NonNullList.create[Ingredient] + ingredients.add(Ingredient.of(Loot.disksForCycling.toArray: _*)) + ingredients.add(Ingredient.of(api.Items.get(Constants.ItemName.Wrench).createItemStack(1))) + + override def matches(crafting: CraftingInventory, world: World): Boolean = { val stacks = collectStacks(crafting).toArray stacks.length == 2 && stacks.exists(Loot.isLootDisk) && stacks.exists(Wrench.isWrench) } - override def getCraftingResult(crafting: InventoryCrafting): ItemStack = { + override def assemble(crafting: CraftingInventory): ItemStack = { val lootDiskStacks = Loot.disksForCycling collectStacks(crafting).find(Loot.isLootDisk) match { case Some(lootDisk) if lootDiskStacks.nonEmpty => @@ -31,18 +39,21 @@ class LootDiskCyclingRecipe extends IForgeRegistryEntry.Impl[IRecipe] with IReci } } - def getLootFactoryName(stack: ItemStack): String = stack.getTagCompound.getString(Settings.namespace + "lootFactory") + def getLootFactoryName(stack: ItemStack): String = stack.getTag.getString(Settings.namespace + "lootFactory") - def collectStacks(crafting: InventoryCrafting): immutable.IndexedSeq[ItemStack] = (0 until crafting.getSizeInventory).flatMap(i => StackOption(crafting.getStackInSlot(i))) + def collectStacks(crafting: CraftingInventory): immutable.IndexedSeq[ItemStack] = (0 until crafting.getContainerSize).flatMap(i => StackOption(crafting.getItem(i))) - override def canFit(width: Int, height: Int): Boolean = width * height >= 2 + override def canCraftInDimensions(width: Int, height: Int): Boolean = width * height >= 2 - override def getRecipeOutput: ItemStack = ItemStack.EMPTY + override def getResultItem = Loot.disksForCycling.headOption match { + case Some(lootDisk) => lootDisk + case _ => ItemStack.EMPTY + } - override def getRemainingItems(crafting: InventoryCrafting): NonNullList[ItemStack] = { - val result = NonNullList.withSize[ItemStack](crafting.getSizeInventory, ItemStack.EMPTY) - for (slot <- 0 until crafting.getSizeInventory) { - val stack = crafting.getStackInSlot(slot) + override def getRemainingItems(crafting: CraftingInventory): NonNullList[ItemStack] = { + val result = NonNullList.withSize[ItemStack](crafting.getContainerSize, ItemStack.EMPTY) + for (slot <- 0 until crafting.getContainerSize) { + val stack = crafting.getItem(slot) if (Wrench.isWrench(stack)) { result.set(slot, stack.copy()) stack.setCount(0) @@ -50,4 +61,8 @@ class LootDiskCyclingRecipe extends IForgeRegistryEntry.Impl[IRecipe] with IReci } result } + + override def getIngredients = ingredients + + override def getSerializer = RecipeSerializers.CRAFTING_LOOTDISK_CYCLING } diff --git a/src/main/scala/li/cil/oc/common/recipe/RecipeSerializers.java b/src/main/scala/li/cil/oc/common/recipe/RecipeSerializers.java new file mode 100644 index 0000000000..24d5c7f666 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/recipe/RecipeSerializers.java @@ -0,0 +1,40 @@ +package li.cil.oc.common.recipe; + +import li.cil.oc.OpenComputers; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.item.crafting.SpecialRecipeSerializer; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.registries.ObjectHolder; + +@ObjectHolder("opencomputers") +public class RecipeSerializers { + public static final IRecipeSerializer CRAFTING_LOOTDISK_CYCLING = null; + public static final IRecipeSerializer CRAFTING_COLORIZE = null; + public static final IRecipeSerializer CRAFTING_DECOLORIZE = null; + public static final IRecipeSerializer CRAFTING_SHAPED_EXTENDED = null; + public static final IRecipeSerializer CRAFTING_SHAPELESS_EXTENDED = null; + + @SubscribeEvent + public static void registerSerializers(RegistryEvent.Register> e) { + register(e.getRegistry(), "crafting_lootdisk_cycling", new SpecialRecipeSerializer<>(LootDiskCyclingRecipe::new)); + register(e.getRegistry(), "crafting_colorize", new ItemSpecialSerializer<>(ColorizeRecipe::new, ColorizeRecipe::targetItem)); + register(e.getRegistry(), "crafting_decolorize", new ItemSpecialSerializer<>(DecolorizeRecipe::new, DecolorizeRecipe::targetItem)); + register(e.getRegistry(), "crafting_shaped_extended", new ExtendedShapedRecipe.Serializer()); + register(e.getRegistry(), "crafting_shapeless_extended", new ExtendedShapelessRecipe.Serializer()); + } + + private static > & IRecipeSerializer> + void register(IForgeRegistry> registry, String name, S serializer) { + + serializer.setRegistryName(new ResourceLocation(OpenComputers.ID(), name)); + registry.register(serializer); + } + + private RecipeSerializers() { + throw new Error(); + } +} diff --git a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala b/src/main/scala/li/cil/oc/common/recipe/Recipes.scala deleted file mode 100644 index 93589d601b..0000000000 --- a/src/main/scala/li/cil/oc/common/recipe/Recipes.scala +++ /dev/null @@ -1,516 +0,0 @@ -package li.cil.oc.common.recipe - -import java.io.File -import java.io.FileReader - -import com.typesafe.config._ -import li.cil.oc._ -import li.cil.oc.common.Loot -import li.cil.oc.common.block.SimpleBlock -import li.cil.oc.common.init.Items -import li.cil.oc.common.item.Delegator -import li.cil.oc.common.item.data.PrintData -import li.cil.oc.common.item.traits.Delegate -import li.cil.oc.common.item.traits.SimpleItem -import li.cil.oc.integration.util.ItemBlacklist -import li.cil.oc.util.Color -import net.minecraft.block.Block -import net.minecraft.item.Item -import net.minecraft.item.ItemBlock -import net.minecraft.item.ItemStack -import net.minecraft.item.crafting.IRecipe -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.ResourceLocation -import net.minecraft.util.registry.RegistryNamespaced -import net.minecraftforge.fluids.FluidRegistry -import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fml.common.Loader -import net.minecraftforge.fml.common.registry.GameRegistry -import net.minecraftforge.oredict.OreDictionary -import net.minecraftforge.oredict.RecipeSorter -import net.minecraftforge.oredict.RecipeSorter.Category -import net.minecraftforge.registries.{GameData, IForgeRegistryEntry} -import org.apache.commons.io.FileUtils - -import scala.collection.convert.WrapAsScala._ -import scala.collection.mutable - -object Recipes { - val list: mutable.LinkedHashMap[ItemStack, String] = mutable.LinkedHashMap.empty[ItemStack, String] - val oreDictEntries: mutable.LinkedHashMap[String, ItemStack] = mutable.LinkedHashMap.empty[String, ItemStack] - var hadErrors = false - val recipeHandlers: mutable.LinkedHashMap[String, (ItemStack, Config) => Unit] = mutable.LinkedHashMap.empty[String, (ItemStack, Config) => Unit] - - def registerRecipeHandler(name: String, recipe: (ItemStack, Config) => Unit): Unit = { - recipeHandlers += name -> recipe - } - - def addBlock(instance: Block, name: String, oreDict: String*): Block = { - Items.registerBlock(instance, name) - addRecipe(new ItemStack(instance), name) - register(instance match { - case simple: SimpleBlock => simple.createItemStack() - case _ => new ItemStack(instance) - }, oreDict: _*) - instance - } - - def addSubItem[T <: Delegate](delegate: T, name: String, oreDict: String*): T = { - Items.registerItem(delegate, name) - addRecipe(delegate.createItemStack(), name) - register(delegate.createItemStack(), oreDict: _*) - delegate - } - - def addItem(instance: Item, name: String, oreDict: String*): Item = { - Items.registerItem(instance, name) - addRecipe(new ItemStack(instance), name) - register(instance match { - case simple: SimpleItem => simple.createItemStack() - case _ => new ItemStack(instance) - }, oreDict: _*) - instance - } - - def addSubItem[T <: common.item.traits.Delegate](delegate: T, name: String, registerRecipe: Boolean, oreDict: String*): T = { - Items.registerItem(delegate, name) - if (registerRecipe) { - addRecipe(delegate.createItemStack(), name) - register(delegate.createItemStack(), oreDict: _*) - } - else { - ItemBlacklist.hide(delegate) - } - delegate - } - - def addStack(stack: ItemStack, name: String, oreDict: String*): ItemStack = { - Items.registerStack(stack, name) - addRecipe(stack, name) - register(stack, oreDict: _*) - stack - } - - def addRecipe(stack: ItemStack, name: String) { - list += stack -> name - } - - private def register(item: ItemStack, names: String*) { - for (name <- names if name != null) { - oreDictEntries += name -> item - } - } - - def init() { - RecipeSorter.register(Settings.namespace + "extshaped", classOf[ExtendedShapedOreRecipe], Category.SHAPED, "after:forge:shapedore") - RecipeSorter.register(Settings.namespace + "extshapeless", classOf[ExtendedShapelessOreRecipe], Category.SHAPELESS, "after:forge:shapelessore") - RecipeSorter.register(Settings.namespace + "colorizer", classOf[ColorizeRecipe], Category.SHAPELESS, "after:forge:shapelessore") - RecipeSorter.register(Settings.namespace + "decolorizer", classOf[DecolorizeRecipe], Category.SHAPELESS, "after:oc:colorizer") - RecipeSorter.register(Settings.namespace + "lootcycler", classOf[LootDiskCyclingRecipe], Category.SHAPELESS, "after:forge:shapelessore") - - for ((name, stack) <- oreDictEntries) { - if (!OreDictionary.getOres(name).contains(stack)) { - OreDictionary.registerOre(name, stack) - } - } - oreDictEntries.clear() - - try { - val recipeSets = Array("default", "hardmode", "gregtech", "peaceful") - val recipeDirectory = new File(Loader.instance.getConfigDir + File.separator + "opencomputers") - val userRecipes = new File(recipeDirectory, "user.recipes") - userRecipes.getParentFile.mkdirs() - if (!userRecipes.exists()) { - FileUtils.copyURLToFile(getClass.getResource("/assets/opencomputers/recipes/user.recipes"), userRecipes) - } - for (recipeSet <- recipeSets) { - FileUtils.copyURLToFile(getClass.getResource(s"/assets/opencomputers/recipes/$recipeSet.recipes"), new File(recipeDirectory, s"$recipeSet.recipes")) - } - lazy val config: ConfigParseOptions = ConfigParseOptions.defaults. - setSyntax(ConfigSyntax.CONF). - setIncluder(new ConfigIncluder with ConfigIncluderFile { - var fallback: ConfigIncluder = _ - - override def withFallback(fallback: ConfigIncluder): ConfigIncluder = { - this.fallback = fallback - this - } - - override def include(context: ConfigIncludeContext, what: String): ConfigObject = fallback.include(context, what) - - override def includeFile(context: ConfigIncludeContext, what: File): ConfigObject = { - val in = if (what.isAbsolute) new FileReader(what) else new FileReader(new File(userRecipes.getParentFile, what.getPath)) - val result = ConfigFactory.parseReader(in, config) - in.close() - result.root() - } - }) - val recipes = ConfigFactory.parseFile(userRecipes, config) - - // Register all known recipes. - for ((stack, name) <- list) { - if (recipes.hasPath(name)) { - val value = recipes.getValue(name) - value.valueType match { - case ConfigValueType.OBJECT => - addRecipe(stack, recipes.getConfig(name), s"'$name'") - case ConfigValueType.BOOLEAN => - // Explicitly disabled, keep in NEI if true. - if (!value.unwrapped.asInstanceOf[Boolean]) { - hide(stack) - } - case _ => - OpenComputers.log.error(s"Failed adding recipe for '$name', you will not be able to craft this item. The error was: Invalid value for recipe.") - hadErrors = true - } - } - else { - OpenComputers.log.warn(s"No recipe for '$name', you will not be able to craft this item. To suppress this warning, disable the recipe (assign `false` to it).") - hadErrors = true - } - } - - // Register all unknown recipes. Well. Loot disk recipes. - if (recipes.hasPath("lootdisks")) try { - val lootRecipes = recipes.getConfigList("lootdisks") - val lootStacks = Loot.globalDisks.map(_._1) - for (recipe <- lootRecipes) { - val name = recipe.getString("name") - lootStacks.find(s => s.getTagCompound.getString(Settings.namespace + "lootFactory") == name) match { - case Some(stack) => addRecipe(stack, recipe, s"loot disk '$name'") - case _ => - OpenComputers.log.warn(s"Failed adding recipe for loot disk '$name': No such global loot disk.") - hadErrors = true - } - } - } - catch { - case t: Throwable => - OpenComputers.log.warn("Failed parsing loot disk recipes.", t) - hadErrors = true - } - - if (recipes.hasPath("generic")) try { - val genericRecipes = recipes.getConfigList("generic") - for (recipe <- genericRecipes) { - val result = recipe.getValue("result").unwrapped() - parseIngredient(result) match { - case stack: ItemStack => addRecipe(stack, recipe, s"'$result'") - case _ => - OpenComputers.log.warn(s"Failed adding generic recipe for '$result': Invalid output (make sure it's not an OreDictionary name).") - hadErrors = true - } - } - } - catch { - case t: Throwable => - OpenComputers.log.warn("Failed parsing generic recipes.", t) - hadErrors = true - } - - // Recrafting operations. - val cable = api.Items.get(Constants.BlockName.Cable) - val chamelium = api.Items.get(Constants.ItemName.Chamelium) - val chameliumBlock = api.Items.get(Constants.BlockName.ChameliumBlock) - val drone = api.Items.get(Constants.ItemName.Drone) - val eeprom = api.Items.get(Constants.ItemName.EEPROM) - val floppy = api.Items.get(Constants.ItemName.Floppy) - val hoverBoots = api.Items.get(Constants.ItemName.HoverBoots) - val mcu = api.Items.get(Constants.BlockName.Microcontroller) - val navigationUpgrade = api.Items.get(Constants.ItemName.NavigationUpgrade) - val print = api.Items.get(Constants.BlockName.Print) - val relay = api.Items.get(Constants.BlockName.Relay) - val robot = api.Items.get(Constants.BlockName.Robot) - val tablet = api.Items.get(Constants.ItemName.Tablet) - val linkedCard = api.Items.get(Constants.ItemName.LinkedCard) - - // Navigation upgrade recrafting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - navigationUpgrade.createItemStack(1), - navigationUpgrade.createItemStack(1), new ItemStack(net.minecraft.init.Items.FILLED_MAP, 1, OreDictionary.WILDCARD_VALUE))) - - // Floppy disk coloring. - for (dye <- Color.dyes) { - val result = floppy.createItemStack(1) - val tag = new NBTTagCompound() - tag.setInteger(Settings.namespace + "color", Color.dyes.indexOf(dye)) - result.setTagCompound(tag) - Recipes.addRecipe(new ExtendedShapelessOreRecipe(result, floppy.createItemStack(1), dye)) - } - - // Microcontroller recrafting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - mcu.createItemStack(1), - mcu.createItemStack(1), eeprom.createItemStack(1))) - - // Drone recrafting. - Recipes.addRecipe(new ExtendedFuzzyShapelessRecipe( - drone.createItemStack(1), - drone.createItemStack(1), eeprom.createItemStack(1))) - - // EEPROM copying via crafting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - eeprom.createItemStack(2), - eeprom.createItemStack(1), eeprom.createItemStack(1))) - - // Robot recrafting. - Recipes.addRecipe(new ExtendedFuzzyShapelessRecipe( - robot.createItemStack(1), - robot.createItemStack(1), eeprom.createItemStack(1))) - - // Tablet recrafting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - tablet.createItemStack(1), - tablet.createItemStack(1), eeprom.createItemStack(1))) - - // Chamelium block splitting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - chamelium.createItemStack(9), - chameliumBlock.createItemStack(1))) - - // Chamelium dying. - for ((dye, meta) <- Color.dyes.zipWithIndex) { - val result = chameliumBlock.createItemStack(1) - result.setItemDamage(meta) - val input = chameliumBlock.createItemStack(1) - input.setItemDamage(OreDictionary.WILDCARD_VALUE) - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - result, - input, dye)) - } - - // Print beaconification. - val beaconPrint = print.createItemStack(1) - - { - val printData = new PrintData(beaconPrint) - printData.isBeaconBase = true - printData.save(beaconPrint) - } - - for (block <- Array( - net.minecraft.init.Blocks.IRON_BLOCK, - net.minecraft.init.Blocks.GOLD_BLOCK, - net.minecraft.init.Blocks.EMERALD_BLOCK, - net.minecraft.init.Blocks.DIAMOND_BLOCK - )) { - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - beaconPrint, - print.createItemStack(1), new ItemStack(block))) - } - - // Floppy disk formatting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe(floppy.createItemStack(1), floppy.createItemStack(1))) - - // Hard disk formatting. - val hdds = Array( - api.Items.get(Constants.ItemName.HDDTier1), - api.Items.get(Constants.ItemName.HDDTier2), - api.Items.get(Constants.ItemName.HDDTier3) - ) - for (hdd <- hdds) { - Recipes.addRecipe(new ExtendedShapelessOreRecipe(hdd.createItemStack(1), hdd.createItemStack(1))) - } - - // EEPROM formatting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe(eeprom.createItemStack(1), eeprom.createItemStack(1))) - - // Print light value increments. - val lightPrint = print.createItemStack(1) - - { - val printData = new PrintData(lightPrint) - printData.lightLevel = 1 - printData.save(lightPrint) - } - - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - lightPrint, - print.createItemStack(1), new ItemStack(net.minecraft.init.Items.GLOWSTONE_DUST))) - - { - val printData = new PrintData(lightPrint) - printData.lightLevel = 4 - printData.save(lightPrint) - } - - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - lightPrint, - print.createItemStack(1), new ItemStack(net.minecraft.init.Blocks.GLOWSTONE))) - - // Hover Boot dyeing - Recipes.addRecipe(new ColorizeRecipe(hoverBoots.item()), "colorizeBoots") - Recipes.addRecipe(new DecolorizeRecipe(hoverBoots.item()), "decolorizeBoots") - - // Cable dyeing - Recipes.addRecipe(new ColorizeRecipe(cable.block()), "colorizeCable") - Recipes.addRecipe(new DecolorizeRecipe(cable.block()), "decolorizeCable") - - // Loot disk cycling. - if (Settings.get.lootRecrafting) { - Recipes.addRecipe(new LootDiskCyclingRecipe(), "lootCycling") - } - - // link card copying via crafting. - Recipes.addRecipe(new ExtendedShapelessOreRecipe( - linkedCard.createItemStack(2), - linkedCard.createItemStack(1), linkedCard.createItemStack(1))) - - } - catch { - case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e) - } - list.clear() - } - - private def addRecipe(output: ItemStack, recipe: Config, name: String) = try { - val recipeType = tryGetType(recipe) - recipeHandlers.get(recipeType) match { - case Some(recipeHandler) => recipeHandler(output, recipe) - case _ => - OpenComputers.log.error(s"Failed adding recipe for $name, you will not be able to craft this item. The error was: Invalid recipe type '$recipeType'.") - hadErrors = true - } - } - catch { - case e: RecipeException => - OpenComputers.log.error(s"Failed adding recipe for $name, you will not be able to craft this item.", e) - hadErrors = true - } - - def tryGetCount(recipe: Config): Int = if (recipe.hasPath("output")) recipe.getInt("output") else 1 - - def parseIngredient(entry: AnyRef): AnyRef = entry match { - case map: java.util.Map[AnyRef, AnyRef]@unchecked => - if (map.contains("oreDict")) { - map.get("oreDict") match { - case value: String => value - case other => throw new RecipeException(s"Invalid name in recipe (not a string: $other).") - } - } - else if (map.contains("item")) { - map.get("item") match { - case name: String => - findItem(name) match { - case Some(item: Item) => new ItemStack(item, 1, tryGetId(map)) - case _ => throw new RecipeException(s"No item found with name '$name'.") - } - case id: Number => new ItemStack(validateItemId(id), 1, tryGetId(map)) - case other => throw new RecipeException(s"Invalid item name in recipe (not a string: $other).") - } - } - else if (map.contains("block")) { - map.get("block") match { - case name: String => - findBlock(name) match { - case Some(block: Block) => new ItemStack(block, 1, tryGetId(map)) - case _ => throw new RecipeException(s"No block found with name '$name'.") - } - case id: Number => new ItemStack(validateBlockId(id), 1, tryGetId(map)) - case other => throw new RecipeException(s"Invalid block name (not a string: $other).") - } - } - else throw new RecipeException("Invalid ingredient type (no oreDict, item or block entry).") - case name: String => - if (name == null || name.trim.isEmpty) ItemStack.EMPTY - else if (OreDictionary.getOres(name) != null && !OreDictionary.getOres(name).isEmpty) name - else { - findItem(name) match { - case Some(item: Item) => new ItemStack(item, 1, 0) - case _ => - findBlock(name) match { - case Some(block: Block) => new ItemStack(block, 1, 0) - case _ => throw new RecipeException(s"No ore dictionary entry, item or block found for ingredient with name '$name'.") - } - } - } - case other => throw new RecipeException(s"Invalid ingredient type (not a map or string): $other") - } - - def parseFluidIngredient(entry: Config): Option[FluidStack] = { - val fluid = FluidRegistry.getFluid(entry.getString("name")) - val amount = - if (entry.hasPath("amount")) entry.getInt("amount") - else 1000 - Option(new FluidStack(fluid, amount)) - } - - private def findItem(name: String) = getObjectWithoutFallback(Item.REGISTRY, name).orElse(Item.REGISTRY.find { - case item: Item => item.getUnlocalizedName == name || item.getUnlocalizedName == "item." + name || Item.REGISTRY.getNameForObject(item).toString == name - case _ => false - }) - - private def findBlock(name: String) = getObjectWithoutFallback(Block.REGISTRY.asInstanceOf[RegistryNamespaced[ResourceLocation, Block]], name).orElse(Block.REGISTRY.find { - case block: Block => block.getUnlocalizedName == name || block.getUnlocalizedName == "tile." + name || Block.REGISTRY.getNameForObject(block).toString == name - case _ => false - }) - - private def getObjectWithoutFallback[V](registry: RegistryNamespaced[ResourceLocation, V], key: String) = { - val loc = new ResourceLocation(key) - if (registry.containsKey(loc)) Option(registry.getObject(loc)) - else None - } - - private def tryGetType(recipe: Config) = if (recipe.hasPath("type")) recipe.getString("type") else "shaped" - - private def tryGetId(ingredient: java.util.Map[AnyRef, AnyRef]): Int = - if (ingredient.contains("subID")) ingredient.get("subID") match { - case id: Number => id.intValue - case "any" => OreDictionary.WILDCARD_VALUE - case id: String => Integer.valueOf(id) - case _ => 0 - } else 0 - - private def validateBlockId(id: Number) = { - val index = id.intValue - val block = Block.getBlockById(index) - if (block == null) throw new RecipeException(s"Invalid block ID: $index") - block - } - - private def validateItemId(id: Number) = { - val index = id.intValue - val item = Item.getItemById(index) - if (item == null) throw new RecipeException(s"Invalid item ID: $index") - item - } - - private def hide(value: ItemStack) { - Delegator.subItem(value) match { - case Some(stack) => - stack.showInItemList = false - case _ => - } - value.getItem match { - case simple: SimpleItem => - simple.setCreativeTab(null) - case _ => - } - value.getItem match { - case itemBlock: ItemBlock => itemBlock.getBlock match { - case simple: SimpleBlock => - simple.setCreativeTab(null) - ItemBlacklist.hide(simple) - case _ => - } - case _ => - } - } - - class RecipeException(message: String) extends RuntimeException(message) - - def addRecipe(recipe: IForgeRegistryEntry.Impl[IRecipe], group: String): IRecipe = GameData.register_impl(recipe.setRegistryName(Settings.resourceDomain, group)) - - private var recipeCounter: Int = 0 - - def addRecipe(recipe: IForgeRegistryEntry.Impl[IRecipe]): Unit = recipe match { - case r: IRecipe => r.getRecipeOutput match { - case stack: ItemStack if !stack.isEmpty => - // Who cares about recipe names? - addRecipe(recipe, stack.getItem.getRegistryName.getResourcePath + recipeCounter.toString) - recipeCounter += 1 - case _ => throw new IllegalArgumentException("invalid recipe name: " + r.getRecipeOutput) - } - case _ => throw new IllegalArgumentException("invalid recipe name: " + recipe) - } -} diff --git a/src/main/scala/li/cil/oc/common/template/AssemblerTemplates.scala b/src/main/scala/li/cil/oc/common/template/AssemblerTemplates.scala index 6928527b22..6b0e0b2d9b 100644 --- a/src/main/scala/li/cil/oc/common/template/AssemblerTemplates.scala +++ b/src/main/scala/li/cil/oc/common/template/AssemblerTemplates.scala @@ -12,7 +12,7 @@ import li.cil.oc.common.Tier import li.cil.oc.util.ExtendedNBT._ import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.util.text.ITextComponent import net.minecraftforge.common.util.Constants.NBT @@ -26,14 +26,14 @@ object AssemblerTemplates { private val templateFilters = mutable.ArrayBuffer.empty[Method] - def add(template: NBTTagCompound): Unit = { + def add(template: CompoundNBT): Unit = { val selector = IMC.getStaticMethod(template.getString("select"), classOf[ItemStack]) val validator = IMC.getStaticMethod(template.getString("validate"), classOf[IInventory]) val assembler = IMC.getStaticMethod(template.getString("assemble"), classOf[IInventory]) val hostClass = tryGetHostClass(template.getString("hostClass")) - val containerSlots = template.getTagList("containerSlots", NBT.TAG_COMPOUND).map((tag: NBTTagCompound) => parseSlot(tag, Some(Slot.Container), hostClass)).take(3).padTo(3, NoSlot).toArray - val upgradeSlots = template.getTagList("upgradeSlots", NBT.TAG_COMPOUND).map((tag: NBTTagCompound) => parseSlot(tag, Some(Slot.Upgrade), hostClass)).take(9).padTo(9, NoSlot).toArray - val componentSlots = template.getTagList("componentSlots", NBT.TAG_COMPOUND).map((tag: NBTTagCompound) => parseSlot(tag, None, hostClass)).take(9).padTo(9, NoSlot).toArray + val containerSlots = template.getList("containerSlots", NBT.TAG_COMPOUND).map((tag: CompoundNBT) => parseSlot(tag, Some(Slot.Container), hostClass)).take(3).padTo(3, NoSlot).toArray + val upgradeSlots = template.getList("upgradeSlots", NBT.TAG_COMPOUND).map((tag: CompoundNBT) => parseSlot(tag, Some(Slot.Upgrade), hostClass)).take(9).padTo(9, NoSlot).toArray + val componentSlots = template.getList("componentSlots", NBT.TAG_COMPOUND).map((tag: CompoundNBT) => parseSlot(tag, None, hostClass)).take(9).padTo(9, NoSlot).toArray templates += new Template(selector, validator, assembler, containerSlots, upgradeSlots, componentSlots) } @@ -73,7 +73,7 @@ object AssemblerTemplates { class Slot(val kind: String, val tier: Int, val validator: Option[Method], val hostClass: Option[Class[_ <: EnvironmentHost]]) { def validate(inventory: IInventory, slot: Int, stack: ItemStack) = validator match { - case Some(method) => IMC.tryInvokeStatic(method, inventory, slot.underlying(), tier.underlying(), stack)(false) + case Some(method) => IMC.tryInvokeStatic(method, inventory, Integer.valueOf(slot), Integer.valueOf(tier), stack)(false) case _ => Option(hostClass.fold(api.Driver.driverFor(stack))(api.Driver.driverFor(stack, _))) match { case Some(driver) => try driver.slot(stack) == kind && driver.tier(stack) <= tier catch { case t: AbstractMethodError => @@ -85,10 +85,10 @@ object AssemblerTemplates { } } - private def parseSlot(nbt: NBTTagCompound, kindOverride: Option[String], hostClass: Option[Class[_ <: EnvironmentHost]]) = { - val kind = kindOverride.getOrElse(if (nbt.hasKey("type")) nbt.getString("type") else Slot.None) - val tier = if (nbt.hasKey("tier")) nbt.getInteger("tier") else Tier.Any - val validator = if (nbt.hasKey("validate")) Option(IMC.getStaticMethod(nbt.getString("validate"), classOf[IInventory], classOf[Int], classOf[Int], classOf[ItemStack])) else None + private def parseSlot(nbt: CompoundNBT, kindOverride: Option[String], hostClass: Option[Class[_ <: EnvironmentHost]]) = { + val kind = kindOverride.getOrElse(if (nbt.contains("type")) nbt.getString("type") else Slot.None) + val tier = if (nbt.contains("tier")) nbt.getInt("tier") else Tier.Any + val validator = if (nbt.contains("validate")) Option(IMC.getStaticMethod(nbt.getString("validate"), classOf[IInventory], classOf[Int], classOf[Int], classOf[ItemStack])) else None new Slot(kind, tier, validator, hostClass) } diff --git a/src/main/scala/li/cil/oc/common/template/DisassemblerTemplates.scala b/src/main/scala/li/cil/oc/common/template/DisassemblerTemplates.scala index 42a4733616..fe86a58cd6 100644 --- a/src/main/scala/li/cil/oc/common/template/DisassemblerTemplates.scala +++ b/src/main/scala/li/cil/oc/common/template/DisassemblerTemplates.scala @@ -5,14 +5,14 @@ import java.lang.reflect.Method import li.cil.oc.OpenComputers import li.cil.oc.common.IMC import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import scala.collection.mutable object DisassemblerTemplates { private val templates = mutable.ArrayBuffer.empty[Template] - def add(template: NBTTagCompound): Unit = try { + def add(template: CompoundNBT): Unit = try { val selector = IMC.getStaticMethod(template.getString("select"), classOf[ItemStack]) val disassembler = IMC.getStaticMethod(template.getString("disassemble"), classOf[ItemStack], classOf[Array[ItemStack]]) diff --git a/src/main/scala/li/cil/oc/common/template/DroneTemplate.scala b/src/main/scala/li/cil/oc/common/template/DroneTemplate.scala index 1ba28adb26..0b34419bd4 100644 --- a/src/main/scala/li/cil/oc/common/template/DroneTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/DroneTemplate.scala @@ -13,7 +13,8 @@ import li.cil.oc.util.ItemUtils import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ object DroneTemplate extends Template { override protected val suggestedComponents = Array( @@ -30,14 +31,14 @@ object DroneTemplate extends Template { def validate(inventory: IInventory): Array[AnyRef] = validateComputer(inventory) def assemble(inventory: IInventory) = { - val items = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot) + val items = (0 until inventory.getContainerSize).map(inventory.getItem) val data = new DroneData() data.tier = caseTier(inventory) data.name = RobotData.randomName data.components = items.drop(1).filter(!_.isEmpty).toArray data.storedEnergy = Settings.get.bufferDrone.toInt val stack = api.Items.get(Constants.ItemName.Drone).createItemStack(1) - data.save(stack) + data.saveData(stack) val energy = Settings.get.droneBaseCost + complexity(inventory) * Settings.get.droneComplexityCost Array(stack, Double.box(energy)) @@ -139,5 +140,5 @@ object DroneTemplate extends Template { else if (caseTier(inventory) == Tier.Four) 9001 // Creative else 5 - override protected def caseTier(inventory: IInventory) = ItemUtils.caseTier(inventory.getStackInSlot(0)) + override protected def caseTier(inventory: IInventory) = ItemUtils.caseTier(inventory.getItem(0)) } diff --git a/src/main/scala/li/cil/oc/common/template/MicrocontrollerTemplate.scala b/src/main/scala/li/cil/oc/common/template/MicrocontrollerTemplate.scala index 333eab5175..ccd2d3ca99 100644 --- a/src/main/scala/li/cil/oc/common/template/MicrocontrollerTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/MicrocontrollerTemplate.scala @@ -12,7 +12,8 @@ import li.cil.oc.util.ItemUtils import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ object MicrocontrollerTemplate extends Template { override protected val suggestedComponents = Array( @@ -29,7 +30,7 @@ object MicrocontrollerTemplate extends Template { def validate(inventory: IInventory): Array[AnyRef] = validateComputer(inventory) def assemble(inventory: IInventory): Array[Object] = { - val items = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot) + val items = (0 until inventory.getContainerSize).map(inventory.getItem) val data = new MicrocontrollerData() data.tier = caseTier(inventory) data.components = items.drop(1).filter(!_.isEmpty).toArray @@ -133,5 +134,5 @@ object MicrocontrollerTemplate extends Template { else if (caseTier(inventory) == Tier.Four) 9001 // Creative else 4 - override protected def caseTier(inventory: IInventory): Int = ItemUtils.caseTier(inventory.getStackInSlot(0)) + override protected def caseTier(inventory: IInventory): Int = ItemUtils.caseTier(inventory.getItem(0)) } diff --git a/src/main/scala/li/cil/oc/common/template/NavigationUpgradeTemplate.scala b/src/main/scala/li/cil/oc/common/template/NavigationUpgradeTemplate.scala index 71b48b3538..99d1a9f50f 100644 --- a/src/main/scala/li/cil/oc/common/template/NavigationUpgradeTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/NavigationUpgradeTemplate.scala @@ -13,7 +13,7 @@ object NavigationUpgradeTemplate { def disassemble(stack: ItemStack, ingredients: Array[ItemStack]) = { val info = new NavigationUpgradeData(stack) ingredients.map { - case part if part.getItem == net.minecraft.init.Items.FILLED_MAP => info.map + case part if part.getItem == net.minecraft.item.Items.FILLED_MAP => info.map case part => part } } diff --git a/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala b/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala index 59ae9f1b7d..e3251b04ee 100644 --- a/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/RobotTemplate.scala @@ -11,7 +11,8 @@ import li.cil.oc.util.ItemUtils import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ object RobotTemplate extends Template { override protected def hostClass = classOf[internal.Robot] @@ -27,7 +28,7 @@ object RobotTemplate extends Template { def validate(inventory: IInventory): Array[AnyRef] = validateComputer(inventory) def assemble(inventory: IInventory) = { - val items = (1 until inventory.getSizeInventory).map(inventory.getStackInSlot) + val items = (1 until inventory.getContainerSize).map(inventory.getItem) val data = new RobotData() data.tier = caseTier(inventory) data.name = RobotData.randomName @@ -187,5 +188,5 @@ object RobotTemplate extends Template { "li.cil.oc.common.template.RobotTemplate.disassemble") } - override protected def caseTier(inventory: IInventory) = ItemUtils.caseTier(inventory.getStackInSlot(0)) + override protected def caseTier(inventory: IInventory) = ItemUtils.caseTier(inventory.getItem(0)) } diff --git a/src/main/scala/li/cil/oc/common/template/ServerTemplate.scala b/src/main/scala/li/cil/oc/common/template/ServerTemplate.scala index 6b4edab25c..ad3a9031b5 100644 --- a/src/main/scala/li/cil/oc/common/template/ServerTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/ServerTemplate.scala @@ -17,8 +17,10 @@ object ServerTemplate { def disassemble(stack: ItemStack, ingredients: Array[ItemStack]) = { val info = new ServerInventory { override def container = stack + + override def rackSlot = -1 } - Array(ingredients, (0 until info.getSizeInventory).map(info.getStackInSlot).filter(null !=).toArray) + Array(ingredients, (0 until info.getContainerSize).map(info.getItem).filter(null !=).toArray) } def register() { diff --git a/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala b/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala index 13bd1c04da..26d48c1626 100644 --- a/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala +++ b/src/main/scala/li/cil/oc/common/template/TabletTemplate.scala @@ -11,7 +11,8 @@ import li.cil.oc.util.ItemUtils import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ object TabletTemplate extends Template { override protected val suggestedComponents = Array( @@ -38,15 +39,15 @@ object TabletTemplate extends Template { def validate(inventory: IInventory): Array[AnyRef] = validateComputer(inventory) def assemble(inventory: IInventory): Array[AnyRef] = { - val items = (1 until inventory.getSizeInventory).map(slot => inventory.getStackInSlot(slot)) + val items = (1 until inventory.getContainerSize).map(slot => inventory.getItem(slot)) val data = new TabletData() - data.tier = ItemUtils.caseTier(inventory.getStackInSlot(0)) + data.tier = ItemUtils.caseTier(inventory.getItem(0)) data.container = items.headOption.getOrElse(ItemStack.EMPTY) data.items = Array(api.Items.get(Constants.BlockName.ScreenTier1).createItemStack(1)) ++ items.drop(if (data.tier == Tier.One) 0 else 1).filter(!_.isEmpty) data.energy = Settings.get.bufferTablet data.maxEnergy = data.energy val stack = api.Items.get(Constants.ItemName.Tablet).createItemStack(1) - data.save(stack) + data.saveData(stack) val energy = Settings.get.tabletBaseCost + complexity(inventory) * Settings.get.tabletComplexityCost Array(stack, Double.box(energy)) @@ -152,5 +153,5 @@ object TabletTemplate extends Template { override protected def maxComplexity(inventory: IInventory) = super.maxComplexity(inventory) / 2 + 5 - override protected def caseTier(inventory: IInventory) = ItemUtils.caseTier(inventory.getStackInSlot(0)) + override protected def caseTier(inventory: IInventory) = ItemUtils.caseTier(inventory.getItem(0)) } diff --git a/src/main/scala/li/cil/oc/common/template/Template.scala b/src/main/scala/li/cil/oc/common/template/Template.scala index e237af2a88..e5a5e7f623 100644 --- a/src/main/scala/li/cil/oc/common/template/Template.scala +++ b/src/main/scala/li/cil/oc/common/template/Template.scala @@ -62,7 +62,7 @@ abstract class Template { } protected def exists(inventory: IInventory, p: ItemStack => Boolean) = { - (0 until inventory.getSizeInventory).exists(slot => StackOption(inventory.getStackInSlot(slot)) match { + (0 until inventory.getContainerSize).exists(slot => StackOption(inventory.getItem(slot)) match { case SomeStack(stack) => p(stack) case _ => false }) @@ -78,8 +78,8 @@ abstract class Template { case _ => false }) - protected def requiresRAM(inventory: IInventory) = !(0 until inventory.getSizeInventory). - map(inventory.getStackInSlot). + protected def requiresRAM(inventory: IInventory) = !(0 until inventory.getContainerSize). + map(inventory.getItem). exists(stack => api.Driver.driverFor(stack, hostClass) match { case driver: api.driver.item.Processor => val architecture = driver.architecture(stack) @@ -104,8 +104,8 @@ abstract class Template { protected def complexity(inventory: IInventory) = { var acc = 0 - for (slot <- 1 until inventory.getSizeInventory) { - val stack = inventory.getStackInSlot(slot) + for (slot <- 1 until inventory.getContainerSize) { + val stack = inventory.getItem(slot) acc += (Option(api.Driver.driverFor(stack, hostClass)) match { case Some(driver: api.driver.item.Processor) => 0 // CPUs are exempt, since they control the limit. case Some(driver: api.driver.item.Container) => (1 + driver.tier(stack)) * 2 @@ -118,8 +118,8 @@ abstract class Template { protected def maxComplexity(inventory: IInventory) = { val caseTier = this.caseTier(inventory) - val cpuTier = (0 until inventory.getSizeInventory).foldRight(0)((slot, acc) => { - val stack = inventory.getStackInSlot(slot) + val cpuTier = (0 until inventory.getContainerSize).foldRight(0)((slot, acc) => { + val stack = inventory.getItem(slot) acc + (api.Driver.driverFor(stack, hostClass) match { case processor: api.driver.item.Processor => processor.tier(stack) case _ => 0 diff --git a/src/main/scala/li/cil/oc/common/template/TemplateBlacklist.scala b/src/main/scala/li/cil/oc/common/template/TemplateBlacklist.scala index edcad23014..158b774161 100644 --- a/src/main/scala/li/cil/oc/common/template/TemplateBlacklist.scala +++ b/src/main/scala/li/cil/oc/common/template/TemplateBlacklist.scala @@ -3,23 +3,25 @@ package li.cil.oc.common.template import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api -import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation +import net.minecraftforge.registries.ForgeRegistries -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object TemplateBlacklist { private lazy val TheBlacklist = { // scnr val pattern = """^([^@]+)(?:@(\d+))?$""".r def parseDescriptor(id: String, meta: Int) = { - val item = Item.REGISTRY.getObject(new ResourceLocation(id)) + val item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(id)) if (item == null) { OpenComputers.log.warn(s"Bad assembler blacklist entry '$id', unknown item id.") None } else { - Option(new ItemStack(item, 1, meta)) + val stack = new ItemStack(item, 1) + stack.setDamageValue(meta) + Option(stack) } } Settings.get.assemblerBlacklist.map { @@ -42,6 +44,6 @@ object TemplateBlacklist { } def filter(stack: ItemStack): Boolean = { - !TheBlacklist.exists(_.isItemEqual(stack)) + !TheBlacklist.exists(_.sameItem(stack)) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala index 0b4ac2e1e5..9c5e6fc246 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala @@ -14,20 +14,28 @@ import li.cil.oc.api.internal import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network._ import li.cil.oc.common.Slot +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.server.{PacketSender => ServerPacketSender} -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.init.SoundEvents +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagList -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.ListNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraft.util.SoundCategory +import net.minecraft.util.SoundEvents import net.minecraftforge.common.util.Constants.NBT -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable -class Adapter extends traits.Environment with traits.ComponentInventory with traits.Tickable with traits.OpenSides with Analyzable with internal.Adapter with DeviceInfo { +class Adapter(selfType: TileEntityType[_ <: Adapter]) extends TileEntity(selfType) with traits.Environment with traits.ComponentInventory + with traits.Tickable with traits.OpenSides with Analyzable with internal.Adapter with DeviceInfo with INamedContainerProvider { + val node = api.Network.newNode(this, Visibility.Network).create() private val blocks = Array.fill[Option[(ManagedEnvironment, DriverBlock)]](6)(None) @@ -49,21 +57,21 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra override protected def defaultState = true - override def setSideOpen(side: EnumFacing, value: Boolean) { + override def setSideOpen(side: Direction, value: Boolean) { super.setSideOpen(side, value) if (isServer) { ServerPacketSender.sendAdapterState(this) - getWorld.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, getWorld.rand.nextFloat() * 0.25f + 0.7f) - getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false) + getLevel.playSound(null, getBlockPos, SoundEvents.PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, getLevel.random.nextFloat() * 0.25f + 0.7f) + getLevel.updateNeighborsAt(getBlockPos, getBlockState.getBlock) neighborChanged(side) } else { - getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) } } // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { (blocks collect { case Some((environment, _)) => environment.node }) ++ @@ -83,10 +91,10 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra } } - def neighborChanged(d: EnumFacing) { + def neighborChanged(d: Direction) { if (node != null && node.network != null) { - val blockPos = getPos.offset(d) - getWorld.getTileEntity(blockPos) match { + val blockPos = getBlockPos.relative(d) + getLevel.getBlockEntity(blockPos) match { case _: traits.Environment => // Don't provide adaption for our stuffs. This is mostly to avoid // cables and other non-functional stuff popping up in the adapter @@ -94,7 +102,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra // but the only 'downside' is that it can't be used to manipulate // inventories, which I actually consider a plus :P case _ => - Option(api.Driver.driverFor(getWorld, blockPos, d)) match { + Option(api.Driver.driverFor(getLevel, blockPos, d)) match { case Some(newDriver) if isSideOpen(d) => blocks(d.ordinal()) match { case Some((oldEnvironment, driver)) => if (newDriver != driver) { @@ -105,13 +113,13 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra node.disconnect(oldEnvironment.node) // Then rebuild - if we have something. - val environment = newDriver.createEnvironment(getWorld, blockPos, d) + val environment = newDriver.createEnvironment(getLevel, blockPos, d) if (environment != null) { blocks(d.ordinal()) = Some((environment, newDriver)) if (environment.canUpdate) { updatingBlocks += environment } - blocksData(d.ordinal()) = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) + blocksData(d.ordinal()) = Some(new BlockData(environment.getClass.getName, new CompoundNBT())) node.connect(environment.node) } } // else: the more things change, the more they stay the same. @@ -120,7 +128,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra return } // A challenger appears. Maybe. - val environment = newDriver.createEnvironment(getWorld, blockPos, d) + val environment = newDriver.createEnvironment(getLevel, blockPos, d) if (environment != null) { blocks(d.ordinal()) = Some((environment, newDriver)) if (environment.canUpdate) { @@ -128,10 +136,10 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra } blocksData(d.ordinal()) match { case Some(data) if data.name == environment.getClass.getName => - environment.load(data.data) + environment.loadData(data.data) case _ => } - blocksData(d.ordinal()) = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) + blocksData(d.ordinal()) = Some(new BlockData(environment.getClass.getName, new CompoundNBT())) node.connect(environment.node) } } @@ -139,7 +147,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra case Some((environment, driver)) => // We had something there, but it's gone now... node.disconnect(environment.node) - environment.save(blocksData(d.ordinal()).get.data) + environment.saveData(blocksData(d.ordinal()).get.data) Option(environment.node).foreach(_.remove()) blocks(d.ordinal()) = None updatingBlocks -= environment @@ -152,7 +160,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra def neighborChanged() { if (node != null && node.network != null) { - for (d <- EnumFacing.values) { + for (d <- Direction.values) { neighborChanged(d) } } @@ -176,57 +184,62 @@ class Adapter extends traits.Environment with traits.ComponentInventory with tra // ----------------------------------------------------------------------- // - override def getSizeInventory = 1 + override def getContainerSize = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, getClass))) match { + override def canPlaceItem(slot: Int, stack: ItemStack) = (slot, Option(Driver.driverFor(stack, getClass))) match { case (0, Some(driver)) => driver.slot(stack) == Slot.Upgrade case _ => false } // ----------------------------------------------------------------------- // + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Adapter(ContainerTypes.ADAPTER, id, playerInventory, this) + + // ----------------------------------------------------------------------- // + private final val BlocksTag = Settings.namespace + "adapter.blocks" private final val BlockNameTag = "name" private final val BlockDataTag = "data" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) - val blocksNbt = nbt.getTagList(BlocksTag, NBT.TAG_COMPOUND) - (0 until (blocksNbt.tagCount min blocksData.length)). - map(blocksNbt.getCompoundTagAt). + val blocksNbt = nbt.getList(BlocksTag, NBT.TAG_COMPOUND) + (0 until (blocksNbt.size min blocksData.length)). + map(blocksNbt.getCompound). zipWithIndex. foreach { case (blockNbt, i) => - if (blockNbt.hasKey(BlockNameTag) && blockNbt.hasKey(BlockDataTag)) { - blocksData(i) = Some(new BlockData(blockNbt.getString(BlockNameTag), blockNbt.getCompoundTag(BlockDataTag))) + if (blockNbt.contains(BlockNameTag) && blockNbt.contains(BlockDataTag)) { + blocksData(i) = Some(new BlockData(blockNbt.getString(BlockNameTag), blockNbt.getCompound(BlockDataTag))) } } } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) - val blocksNbt = new NBTTagList() + val blocksNbt = new ListNBT() for (i <- blocks.indices) { - val blockNbt = new NBTTagCompound() + val blockNbt = new CompoundNBT() blocksData(i) match { case Some(data) => blocks(i) match { - case Some((environment, _)) => environment.save(data.data) + case Some((environment, _)) => environment.saveData(data.data) case _ => } - blockNbt.setString(BlockNameTag, data.name) - blockNbt.setTag(BlockDataTag, data.data) + blockNbt.putString(BlockNameTag, data.name) + blockNbt.put(BlockDataTag, data.data) case _ => } - blocksNbt.appendTag(blockNbt) + blocksNbt.add(blockNbt) } - nbt.setTag(BlocksTag, blocksNbt) + nbt.put(BlocksTag, blocksNbt) } // ----------------------------------------------------------------------- // - private class BlockData(val name: String, val data: NBTTagCompound) + private class BlockData(val name: String, val data: CompoundNBT) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala b/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala index c65c8a1649..85e81df00f 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Assembler.scala @@ -12,20 +12,30 @@ import li.cil.oc.api.machine.Arguments import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.api.network._ +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.template.AssemblerTemplates import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraft.util.text.StringTextComponent +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ + +class Assembler(selfType: TileEntityType[_ <: Assembler]) extends TileEntity(selfType) with traits.Environment with traits.PowerAcceptor + with traits.Inventory with SidedEnvironment with traits.StateAware with traits.Tickable with DeviceInfo with INamedContainerProvider { -class Assembler extends traits.Environment with traits.PowerAcceptor with traits.Inventory with SidedEnvironment with traits.StateAware with traits.Tickable with DeviceInfo { val node = api.Network.newNode(this, Visibility.Network). withComponent("assembler"). withConnector(Settings.get.bufferConverter). @@ -48,15 +58,15 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing) = side != EnumFacing.UP + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction) = side != Direction.UP - override def sidedNode(side: EnumFacing) = if (side != EnumFacing.UP) node else null + override def sidedNode(side: Direction) = if (side != Direction.UP) node else null - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing) = canConnect(side) + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction) = canConnect(side) - override protected def connector(side: EnumFacing) = Option(if (side != EnumFacing.UP) node else null) + override protected def connector(side: Direction) = Option(if (side != Direction.UP) node else null) override def energyThroughput = Settings.get.assemblerRate @@ -68,7 +78,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits // ----------------------------------------------------------------------- // - def canAssemble = AssemblerTemplates.select(getStackInSlot(0)) match { + def canAssemble = AssemblerTemplates.select(getItem(0)) match { case Some(template) => !isAssembling && output.isEmpty && template.validate(this)._1 case _ => false } @@ -82,11 +92,11 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits // ----------------------------------------------------------------------- // def start(finishImmediately: Boolean = false): Boolean = this.synchronized { - AssemblerTemplates.select(getStackInSlot(0)) match { + AssemblerTemplates.select(getItem(0)) match { case Some(template) if !isAssembling && output.isEmpty && template.validate(this)._1 => - for (slot <- 0 until getSizeInventory) { - val stack = getStackInSlot(slot) - if (!stack.isEmpty && !isItemValidForSlot(slot, stack)) return false + for (slot <- 0 until getContainerSize) { + val stack = getItem(slot) + if (!stack.isEmpty && !canPlaceItem(slot, stack)) return false } val (stack, energy) = template.assemble(this) output = StackOption(stack) @@ -99,8 +109,8 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits requiredEnergy = totalRequiredEnergy ServerPacketSender.sendRobotAssembling(this, assembling = true) - for (slot <- 0 until getSizeInventory) updateItems(slot, ItemStack.EMPTY) - markDirty() + for (slot <- 0 until getContainerSize) updateItems(slot, ItemStack.EMPTY) + setChanged() true case _ => false @@ -112,7 +122,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits @Callback(doc = """function(): string, number or boolean -- The current state of the assembler, `busy' or `idle', followed by the progress or template validity, respectively.""") def status(context: Context, args: Arguments): Array[Object] = { if (isAssembling) result("busy", progress) - else AssemblerTemplates.select(getStackInSlot(0)) match { + else AssemblerTemplates.select(getItem(0)) match { case Some(template) if template.validate(this)._1 => result("idle", true) case _ => result("idle", false) } @@ -125,12 +135,12 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits override def updateEntity() { super.updateEntity() - if (!output.isEmpty && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (!output.isEmpty && getLevel.getGameTime % Settings.get.tickFrequency == 0) { val want = math.max(1, math.min(requiredEnergy, Settings.get.assemblerTickAmount * Settings.get.tickFrequency)) val have = want + (if (Settings.get.ignorePower) 0 else node.changeBuffer(-want)) requiredEnergy -= have if (requiredEnergy <= 0) { - setInventorySlotContents(0, output.get) + setItem(0, output.get) output = EmptyStack requiredEnergy = 0 } @@ -145,47 +155,47 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits private final val TotalTag = Settings.namespace + "total" private final val RemainingTag = Settings.namespace + "remaining" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - if (nbt.hasKey(OutputTag)) { - output = StackOption(new ItemStack(nbt.getCompoundTag(OutputTag))) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + if (nbt.contains(OutputTag)) { + output = StackOption(ItemStack.of(nbt.getCompound(OutputTag))) } - else if (nbt.hasKey(OutputTagCompat)) { - output = StackOption(new ItemStack(nbt.getCompoundTag(OutputTagCompat))) + else if (nbt.contains(OutputTagCompat)) { + output = StackOption(ItemStack.of(nbt.getCompound(OutputTagCompat))) } totalRequiredEnergy = nbt.getDouble(TotalTag) requiredEnergy = nbt.getDouble(RemainingTag) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setNewCompoundTag(OutputTag, output.get.writeToNBT) - nbt.setDouble(TotalTag, totalRequiredEnergy) - nbt.setDouble(RemainingTag, requiredEnergy) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + nbt.setNewCompoundTag(OutputTag, output.get.save) + nbt.putDouble(TotalTag, totalRequiredEnergy) + nbt.putDouble(RemainingTag, requiredEnergy) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) requiredEnergy = nbt.getDouble(RemainingTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setDouble(RemainingTag, requiredEnergy) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putDouble(RemainingTag, requiredEnergy) } // ----------------------------------------------------------------------- // - override def getSizeInventory = 22 + override def getContainerSize = 22 - override def getInventoryStackLimit = 1 + override def getMaxStackSize = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack) = + override def canPlaceItem(slot: Int, stack: ItemStack) = if (slot == 0) { !isAssembling && AssemblerTemplates.select(stack).isDefined } - else AssemblerTemplates.select(getStackInSlot(0)) match { + else AssemblerTemplates.select(getItem(0)) match { case Some(template) => val tplSlot = if ((1 until 4) contains slot) template.containerSlots(slot - 1) @@ -195,4 +205,11 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits tplSlot.validate(this, slot, stack) case _ => false } + + // ----------------------------------------------------------------------- // + + override def getDisplayName = StringTextComponent.EMPTY + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Assembler(ContainerTypes.ASSEMBLER, id, playerInventory, this) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Cable.scala b/src/main/scala/li/cil/oc/common/tileentity/Cable.scala index 3bbde82150..131d76cd76 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Cable.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Cable.scala @@ -5,19 +5,21 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.common import li.cil.oc.Constants import li.cil.oc.util.Color -import net.minecraft.item.EnumDyeColor +import net.minecraft.item.DyeColor import li.cil.oc.util.ItemColorizer import net.minecraft.item.Item import net.minecraft.item.ItemStack +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType -class Cable extends traits.Environment with traits.NotAnalyzable with traits.ImmibisMicroblock with traits.Colored { +class Cable(selfType: TileEntityType[_ <: Cable]) extends TileEntity(selfType) with traits.Environment with traits.NotAnalyzable with traits.ImmibisMicroblock with traits.Colored { val node = api.Network.newNode(this, Visibility.None).create() - setColor(Color.rgbValues(EnumDyeColor.SILVER)) + setColor(Color.rgbValues(DyeColor.LIGHT_GRAY)) def createItemStack() = { val stack = api.Items.get(Constants.BlockName.Cable).createItemStack(1) - if (getColor != Color.rgbValues(EnumDyeColor.SILVER)) { + if (getColor != Color.rgbValues(DyeColor.LIGHT_GRAY)) { ItemColorizer.setColor(stack, getColor) } stack @@ -35,10 +37,8 @@ class Cable extends traits.Environment with traits.NotAnalyzable with traits.Imm override protected def onColorChanged() { super.onColorChanged() - if (getWorld != null && isServer) { + if (getLevel != null && isServer) { api.Network.joinOrCreateNetwork(this) } } - - override def getRenderBoundingBox = common.block.Cable.bounds(getWorld, getPos).offset(x, y, z) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Capacitor.scala b/src/main/scala/li/cil/oc/common/tileentity/Capacitor.scala index 31da0e1c21..06bfab5abb 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Capacitor.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Capacitor.scala @@ -10,11 +10,14 @@ import li.cil.oc.api import li.cil.oc.api.driver.DeviceInfo import li.cil.oc.api.network.Node import li.cil.oc.api.network.Visibility -import net.minecraft.util.EnumFacing +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraft.util.math.BlockPos -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ -class Capacitor extends traits.Environment with DeviceInfo { +class Capacitor(selfType: TileEntityType[_ <: Capacitor]) extends TileEntity(selfType) with traits.Environment with DeviceInfo { // Start with maximum theoretical capacity, gets reduced after validation. // This is done so that we don't lose energy while loading. val node = api.Network.newNode(this, Visibility.Network). @@ -37,7 +40,7 @@ class Capacitor extends traits.Environment with DeviceInfo { super.dispose() if (isServer) { indirectNeighbors.map(coordinate => { - if (getWorld.isBlockLoaded(coordinate)) Option(getWorld.getTileEntity(coordinate)) + if (getLevel.isLoaded(coordinate)) Option(getLevel.getBlockEntity(coordinate)) else None }).collect { case Some(capacitor: Capacitor) => capacitor.recomputeCapacity() @@ -57,14 +60,14 @@ class Capacitor extends traits.Environment with DeviceInfo { def recomputeCapacity(updateSecondGradeNeighbors: Boolean = false) { node.setLocalBufferSize( Settings.get.bufferCapacitor + - Settings.get.bufferCapacitorAdjacencyBonus * EnumFacing.values.count(side => { - val blockPos = getPos.offset(side) - getWorld.isBlockLoaded(blockPos) && (getWorld.getTileEntity(blockPos) match { + Settings.get.bufferCapacitorAdjacencyBonus * Direction.values.count(side => { + val blockPos = getBlockPos.relative(side) + getLevel.isLoaded(blockPos) && (getLevel.getBlockEntity(blockPos) match { case capacitor: Capacitor => true case _ => false }) }) + - Settings.get.bufferCapacitorAdjacencyBonus / 2 * indirectNeighbors.count(blockPos => getWorld.isBlockLoaded(blockPos) && (getWorld.getTileEntity(blockPos) match { + Settings.get.bufferCapacitorAdjacencyBonus / 2 * indirectNeighbors.count(blockPos => getLevel.isLoaded(blockPos) && (getLevel.getBlockEntity(blockPos) match { case capacitor: Capacitor => if (updateSecondGradeNeighbors) { capacitor.recomputeCapacity() @@ -74,7 +77,7 @@ class Capacitor extends traits.Environment with DeviceInfo { }))) } - private def indirectNeighbors = EnumFacing.values.map(getPos.offset(_, 2)) + private def indirectNeighbors = Direction.values.map(getBlockPos.relative(_, 2): BlockPos) protected def maxCapacity = Settings.get.bufferCapacitor + Settings.get.bufferCapacitorAdjacencyBonus * 9 } diff --git a/src/main/scala/li/cil/oc/common/tileentity/CarpetedCapacitor.scala b/src/main/scala/li/cil/oc/common/tileentity/CarpetedCapacitor.scala index b355dc9d92..92fc496c09 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/CarpetedCapacitor.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/CarpetedCapacitor.scala @@ -6,16 +6,16 @@ import li.cil.oc.Constants import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute import li.cil.oc.api.driver.DeviceInfo.DeviceClass import li.cil.oc.Settings -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.passive.{EntityOcelot, EntitySheep} +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.passive.{OcelotEntity, SheepEntity} +import net.minecraft.tileentity.TileEntityType import net.minecraft.util.DamageSource -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ -import li.cil.oc.common.tileentity.traits.Tickable +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ -class CarpetedCapacitor extends Capacitor with Tickable { +class CarpetedCapacitor(selfType: TileEntityType[_ <: CarpetedCapacitor]) extends Capacitor(selfType) with traits.Tickable { private final lazy val deviceInfo = Map( DeviceAttribute.Class -> DeviceClass.Power, DeviceAttribute.Description -> "Battery", @@ -26,38 +26,38 @@ class CarpetedCapacitor extends Capacitor with Tickable { override def getDeviceInfo: util.Map[String, String] = deviceInfo - private def _world: net.minecraft.world.World = getWorld + private def _world: net.minecraft.world.World = getLevel private val rng = scala.util.Random private val chance: Double = Settings.get.carpetDamageChance private var nextChanceTime: Long = 0 - private def energyFromGroup(entities: Set[EntityLivingBase], power: Double): Double = { + private def energyFromGroup(entities: Set[LivingEntity], power: Double): Double = { if (entities.size < 2) return 0 def tryDamageOne(): Unit = { for (ent <- entities) { if (rng.nextDouble() < chance) { - ent.attackEntityFrom(DamageSource.GENERIC, 1) - ent.setRevengeTarget(ent) // panic - ent.knockBack(ent, 0, .25, 0) + ent.hurt(DamageSource.GENERIC, 1) + ent.setLastHurtByMob(ent) // panic + ent.knockback(0, .25, 0) // wait a minute before the next possible shock - nextChanceTime = _world.getTotalWorldTime + (20 * 60) + nextChanceTime = _world.getGameTime + (20 * 60) return } } } - if (chance > 0 && nextChanceTime < _world.getTotalWorldTime) { + if (chance > 0 && nextChanceTime < _world.getGameTime) { tryDamageOne() } power } override def updateEntity() { - if (node != null && (_world.getTotalWorldTime + hashCode) % 20 == 0) { - val entities = _world.getEntitiesWithinAABB(classOf[EntityLivingBase], capacitorPowerBounds) - .filter(entity => entity.isEntityAlive) + if (node != null && (_world.getGameTime + hashCode) % 20 == 0) { + val entities = _world.getEntitiesOfClass(classOf[LivingEntity], capacitorPowerBounds) + .filter(entity => entity.isAlive) .toSet - val sheepPower = energyFromGroup(entities.filter(_.isInstanceOf[EntitySheep]), Settings.get.sheepPower) - val ocelotPower = energyFromGroup(entities.filter(_.isInstanceOf[EntityOcelot]), Settings.get.ocelotPower) + val sheepPower = energyFromGroup(entities.filter(_.isInstanceOf[SheepEntity]), Settings.get.sheepPower) + val ocelotPower = energyFromGroup(entities.filter(_.isInstanceOf[OcelotEntity]), Settings.get.ocelotPower) val totalPower = sheepPower + ocelotPower if (totalPower > 0) { node.changeBuffer(totalPower) @@ -65,5 +65,5 @@ class CarpetedCapacitor extends Capacitor with Tickable { } } - private def capacitorPowerBounds = position.offset(EnumFacing.UP).bounds + private def capacitorPowerBounds = position.offset(Direction.UP).bounds } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Case.scala b/src/main/scala/li/cil/oc/common/tileentity/Case.scala index 20d423a0c5..58e1a8ec5a 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Case.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Case.scala @@ -15,19 +15,25 @@ import li.cil.oc.common.InventorySlots import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.block.property.PropertyRunning +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.util.Color -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -import scala.collection.convert.WrapAsJava._ - -class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with traits.Colored with internal.Case with DeviceInfo { - def this() = { - this(0) +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +import scala.collection.convert.ImplicitConversionsToJava._ + +class Case(selfType: TileEntityType[_ <: Case], var tier: Int) extends TileEntity(selfType) with traits.PowerAcceptor with traits.Computer with traits.Colored with internal.Case with DeviceInfo with INamedContainerProvider { + def this(selfType: TileEntityType[_ <: Case]) = { + this(selfType, 0) // If no tier was defined when constructing this case, then we don't yet know the inventory size // this is set back to true when the nbt data is loaded isSizeInventoryReady = false @@ -44,17 +50,17 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with DeviceAttribute.Description -> "Computer", DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, DeviceAttribute.Product -> "Blocker", - DeviceAttribute.Capacity -> getSizeInventory.toString + DeviceAttribute.Capacity -> getContainerSize.toString ) override def getDeviceInfo: util.Map[String, String] = deviceInfo // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing) = side != facing + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction) = side != facing - override protected def connector(side: EnumFacing) = Option(if (side != facing && machine != null) machine.node.asInstanceOf[Connector] else null) + override protected def connector(side: Direction) = Option(if (side != facing && machine != null) machine.node.asInstanceOf[Connector] else null) override def energyThroughput = Settings.get.caseRate(tier) @@ -67,7 +73,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with // ----------------------------------------------------------------------- // override def updateEntity() { - if (isServer && isCreative && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (isServer && isCreative && getLevel.getGameTime % Settings.get.tickFrequency == 0) { // Creative case, make it generate power. node.asInstanceOf[Connector].changeBuffer(Double.PositiveInfinity) } @@ -78,12 +84,12 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with override protected def onRunningChanged(): Unit = { super.onRunningChanged() - getBlockType match { + getBlockState.getBlock match { case block: common.block.Case => { - val state = getWorld.getBlockState(getPos) + val state = getLevel.getBlockState(getBlockPos) // race condition that the world no longer has this block at the position (e.g. it was broken) if (block == state.getBlock) { - getWorld.setBlockState(getPos, state.withProperty(PropertyRunning.Running, Boolean.box(isRunning))) + getLevel.setBlockAndUpdate(getBlockPos, state.setValue(PropertyRunning.Running, Boolean.box(isRunning))) } } case _ => @@ -94,16 +100,16 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with private final val TierTag = Settings.namespace + "tier" - override def readFromNBTForServer(nbt: NBTTagCompound) { + override def loadForServer(nbt: CompoundNBT) { tier = nbt.getByte(TierTag) max 0 min 3 setColor(Color.rgbValues(Color.byTier(tier))) - super.readFromNBTForServer(nbt) + super.loadForServer(nbt) isSizeInventoryReady = true } - override def writeToNBTForServer(nbt: NBTTagCompound) { - nbt.setByte(TierTag, tier.toByte) - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + nbt.putByte(TierTag, tier.toByte) + super.saveForServer(nbt) } // ----------------------------------------------------------------------- // @@ -130,14 +136,19 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with } } - override def getSizeInventory = if (tier < 0 || tier >= InventorySlots.computer.length) 0 else InventorySlots.computer(tier).length + override def getContainerSize = if (tier < 0 || tier >= InventorySlots.computer.length) 0 else InventorySlots.computer(tier).length - override def isUsableByPlayer(player: EntityPlayer) = - super.isUsableByPlayer(player) && (!isCreative || player.capabilities.isCreativeMode) + override def stillValid(player: PlayerEntity) = + super.stillValid(player) && (!isCreative || player.isCreative) - override def isItemValidForSlot(slot: Int, stack: ItemStack) = + override def canPlaceItem(slot: Int, stack: ItemStack) = Option(Driver.driverFor(stack, getClass)).fold(false)(driver => { val provided = InventorySlots.computer(tier)(slot) driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier }) + + // ----------------------------------------------------------------------- // + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Case(ContainerTypes.CASE, id, playerInventory, this, tier) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Charger.scala b/src/main/scala/li/cil/oc/common/tileentity/Charger.scala index 946e5d0b9d..1d8545beb3 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Charger.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Charger.scala @@ -14,25 +14,34 @@ import li.cil.oc.api.nanomachines.Controller import li.cil.oc.api.network._ import li.cil.oc.api.util.StateAware import li.cil.oc.common.Slot +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.entity.Drone import li.cil.oc.integration.util.ItemCharge import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumParticleTypes -import net.minecraft.util.math.Vec3d -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import net.minecraft.nbt.CompoundNBT +import net.minecraft.particles.ParticleTypes +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraft.util.Util +import net.minecraft.util.math.vector.Vector3d +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable -class Charger extends traits.Environment with traits.PowerAcceptor with traits.RedstoneAware with traits.Rotatable with traits.ComponentInventory with traits.Tickable with Analyzable with traits.StateAware with DeviceInfo { +class Charger(selfType: TileEntityType[_ <: Charger]) extends TileEntity(selfType) with traits.Environment with traits.PowerAcceptor with traits.RedstoneAware + with traits.Rotatable with traits.ComponentInventory with traits.Tickable with Analyzable with traits.StateAware with DeviceInfo with INamedContainerProvider { + val node: Connector = api.Network.newNode(this, Visibility.None). withConnector(Settings.get.bufferConverter). create() @@ -57,10 +66,10 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing): Boolean = side != facing + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction): Boolean = side != facing - override protected def connector(side: EnumFacing) = Option(if (side != facing) node else null) + override protected def connector(side: Direction) = Option(if (side != facing) node else null) override def energyThroughput: Double = Settings.get.chargerRate @@ -73,8 +82,8 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R else util.EnumSet.noneOf(classOf[api.util.StateAware.State]) } - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Null = { - player.sendMessage(Localization.Analyzer.ChargerSpeed(chargeSpeed)) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Null = { + player.sendMessage(Localization.Analyzer.ChargerSpeed(chargeSpeed), Util.NIL_UUID) null } @@ -92,11 +101,11 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R super.updateEntity() // Offset by hashcode to avoid all chargers ticking at the same time. - if ((getWorld.getWorldInfo.getWorldTotalTime + math.abs(hashCode())) % 20 == 0) { + if ((getLevel.getLevelData.getGameTime + math.abs(hashCode())) % 20 == 0) { updateConnectors() } - if (isServer && getWorld.getWorldInfo.getWorldTotalTime % Settings.get.tickFrequency == 0) { + if (isServer && getLevel.getLevelData.getGameTime % Settings.get.tickFrequency == 0) { var canCharge = Settings.get.ignorePower // Charging of external devices. @@ -117,7 +126,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R val charge = Settings.get.chargeRateTablet * chargeSpeed * Settings.get.tickFrequency canCharge ||= charge > 0 && node.globalBuffer >= charge * 0.5 if (canCharge) { - (0 until getSizeInventory).map(getStackInSlot).foreach(chargeStack(_, charge)) + (0 until getContainerSize).map(getItem).foreach(chargeStack(_, charge)) } } @@ -140,15 +149,15 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R } } - if (isClient && chargeSpeed > 0 && hasPower && getWorld.getWorldInfo.getWorldTotalTime % 10 == 0) { + if (isClient && chargeSpeed > 0 && hasPower && getLevel.getLevelData.getGameTime % 10 == 0) { connectors.foreach(connector => { val position = connector.pos - val theta = getWorld.rand.nextDouble * Math.PI - val phi = getWorld.rand.nextDouble * Math.PI * 2 + val theta = getLevel.random.nextDouble * Math.PI + val phi = getLevel.random.nextDouble * Math.PI * 2 val dx = 0.45 * Math.sin(theta) * Math.cos(phi) val dy = 0.45 * Math.sin(theta) * Math.sin(phi) val dz = 0.45 * Math.cos(theta) - getWorld.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, position.x + dx, position.y + dz, position.z + dy, 0, 0, 0) + getLevel.addParticle(ParticleTypes.HAPPY_VILLAGER, position.x + dx, position.y + dz, position.z + dy, 0, 0, 0) }) } } @@ -169,40 +178,40 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R private final val InvertSignalTag = Settings.namespace + "invertSignal" private final val InvertSignalTagCompat = "invertSignal" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - if (nbt.hasKey(ChargeSpeedTagCompat)) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + if (nbt.contains(ChargeSpeedTagCompat)) chargeSpeed = nbt.getDouble(ChargeSpeedTagCompat) max 0 min 1 else chargeSpeed = nbt.getDouble(ChargeSpeedTag) max 0 min 1 - if (nbt.hasKey(HasPowerTagCompat)) + if (nbt.contains(HasPowerTagCompat)) hasPower = nbt.getBoolean(HasPowerTagCompat) else hasPower = nbt.getBoolean(HasPowerTag) - if (nbt.hasKey(InvertSignalTagCompat)) + if (nbt.contains(InvertSignalTagCompat)) invertSignal = nbt.getBoolean(InvertSignalTagCompat) else invertSignal = nbt.getBoolean(InvertSignalTag) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setDouble(ChargeSpeedTag, chargeSpeed) - nbt.setBoolean(HasPowerTag, hasPower) - nbt.setBoolean(InvertSignalTag, invertSignal) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + nbt.putDouble(ChargeSpeedTag, chargeSpeed) + nbt.putBoolean(HasPowerTag, hasPower) + nbt.putBoolean(InvertSignalTag, invertSignal) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) chargeSpeed = nbt.getDouble(ChargeSpeedTag) hasPower = nbt.getBoolean(HasPowerTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setDouble(ChargeSpeedTag, chargeSpeed) - nbt.setBoolean(HasPowerTag, hasPower) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putDouble(ChargeSpeedTag, chargeSpeed) + nbt.putBoolean(HasPowerTag, hasPower) } // ----------------------------------------------------------------------- // @@ -213,16 +222,21 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R case _ => false }) - override def getSizeInventory = 1 + override def getContainerSize = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { case (0, Some(driver)) if driver.slot(stack) == Slot.Tablet => true case _ => ItemCharge.canCharge(stack) } // ----------------------------------------------------------------------- // - override def updateRedstoneInput(side: EnumFacing) { + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Charger(ContainerTypes.CHARGER, id, playerInventory, this) + + // ----------------------------------------------------------------------- // + + override def updateRedstoneInput(side: Direction) { super.updateRedstoneInput(side) val signal = getInput.max min 15 @@ -239,20 +253,20 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R } def updateConnectors() { - val robots = EnumFacing.values.map(side => { + val robots = Direction.values.map(side => { val blockPos = BlockPosition(this).offset(side) - if (getWorld.blockExists(blockPos)) Option(getWorld.getTileEntity(blockPos)) + if (getLevel.blockExists(blockPos)) Option(getLevel.getBlockEntity(blockPos)) else None }).collect { case Some(t: RobotProxy) => new RobotChargeable(t.robot) } - val bounds = BlockPosition(this).bounds.grow(1, 1, 1) - val drones = getWorld.getEntitiesWithinAABB(classOf[Drone], bounds).collect { + val bounds = BlockPosition(this).bounds.inflate(1, 1, 1) + val drones = getLevel.getEntitiesOfClass(classOf[Drone], bounds).collect { case drone: Drone => new DroneChargeable(drone) } - val players = getWorld.getEntitiesWithinAABB(classOf[EntityPlayer], bounds).collect { - case player: EntityPlayer => player + val players = getLevel.getEntitiesOfClass(classOf[PlayerEntity], bounds).collect { + case player: PlayerEntity => player } val chargeablePlayers = players.collect { @@ -265,13 +279,13 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R if (connectors.size != newConnectors.length || (connectors.nonEmpty && (connectors -- newConnectors).nonEmpty)) { connectors.clear() connectors ++= newConnectors - getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false) + getLevel.updateNeighborsAt(getBlockPos, getBlockState.getBlock) } // scan players for chargeable equipment equipment.clear() players.foreach { - player => player.inventory.mainInventory.foreach { + player => player.inventory.items.foreach { stack: ItemStack => if (Option(Driver.driverFor(stack, getClass)) match { case Some(driver) if driver.slot(stack) == Slot.Tablet => true @@ -284,7 +298,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R } trait Chargeable { - def pos: Vec3d + def pos: Vector3d def changeBuffer(delta: Double): Double } @@ -299,7 +313,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R } class RobotChargeable(val robot: Robot) extends ConnectorChargeable(robot.node.asInstanceOf[Connector]) { - override def pos: Vec3d = BlockPosition(robot).toVec3 + override def pos: Vector3d = BlockPosition(robot).toVec3 override def equals(obj: scala.Any): Boolean = obj match { case chargeable: RobotChargeable => chargeable.robot == robot @@ -310,7 +324,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R } class DroneChargeable(val drone: Drone) extends ConnectorChargeable(drone.components.node.asInstanceOf[Connector]) { - override def pos: Vec3d = new Vec3d(drone.posX, drone.posY, drone.posZ) + override def pos: Vector3d = new Vector3d(drone.getX, drone.getY, drone.getZ) override def equals(obj: scala.Any): Boolean = obj match { case chargeable: DroneChargeable => chargeable.drone == drone @@ -320,8 +334,8 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R override def hashCode(): Int = drone.hashCode() } - class PlayerChargeable(val player: EntityPlayer) extends Chargeable { - override def pos: Vec3d = new Vec3d(player.posX, player.posY, player.posZ) + class PlayerChargeable(val player: PlayerEntity) extends Chargeable { + override def pos: Vector3d = new Vector3d(player.getX, player.getY, player.getZ) override def changeBuffer(delta: Double): Double = { api.Nanomachines.getController(player) match { diff --git a/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala b/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala index 9d02fb9c9b..69770cb83d 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Disassembler.scala @@ -11,25 +11,33 @@ import li.cil.oc.api.driver.DeviceInfo import li.cil.oc.api.network.Connector import li.cil.oc.api.network.Visibility import li.cil.oc.api.util.StateAware +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.template.DisassemblerTemplates import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.ItemUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable import scala.collection.mutable.ArrayBuffer -class Disassembler extends traits.Environment with traits.PowerAcceptor with traits.Inventory with traits.StateAware with traits.PlayerInputAware with traits.Tickable with DeviceInfo { +class Disassembler(selfType: TileEntityType[_ <: Disassembler]) extends TileEntity(selfType) with traits.Environment with traits.PowerAcceptor + with traits.Inventory with traits.StateAware with traits.PlayerInputAware with traits.Tickable with DeviceInfo with INamedContainerProvider { + val node: Connector = api.Network.newNode(this, Visibility.None). withConnector(Settings.get.bufferConverter). create() @@ -40,7 +48,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra var totalRequiredEnergy = 0.0 - override def getInventoryStackLimit: Int = 1 + override def getMaxStackSize: Int = 1 var buffer = 0.0 @@ -51,7 +59,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra private def setActive(value: Boolean) = if (value != isActive) { isActive = value ServerPacketSender.sendDisassemblerActive(this, isActive) - getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, true) + getLevel.updateNeighborsAt(getBlockPos, getBlockState.getBlock) } private final lazy val deviceInfo = Map( @@ -65,10 +73,10 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing): Boolean = side != EnumFacing.UP + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction): Boolean = side != Direction.UP - override protected def connector(side: EnumFacing) = Option(if (side != EnumFacing.UP) node else null) + override protected def connector(side: Direction) = Option(if (side != Direction.UP) node else null) override def energyThroughput: Double = Settings.get.disassemblerRate @@ -82,10 +90,10 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra override def updateEntity() { super.updateEntity() - if (isServer && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (isServer && getLevel.getGameTime % Settings.get.tickFrequency == 0) { if (queue.isEmpty) { - val instant = disassembleNextInstantly // Is reset via decrStackSize - disassemble(decrStackSize(0, 1), instant) + val instant = disassembleNextInstantly // Is reset via removeItem + disassemble(removeItem(0, 1), instant) setActive(queue.nonEmpty) } else { @@ -100,7 +108,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra while (buffer >= Settings.get.disassemblerItemCost && queue.nonEmpty) { buffer -= Settings.get.disassemblerItemCost val stack = queue.remove(0) - if (disassembleNextInstantly || getWorld.rand.nextDouble >= Settings.get.disassemblerBreakChance) { + if (disassembleNextInstantly || getLevel.random.nextDouble >= Settings.get.disassemblerBreakChance) { drop(stack) } } @@ -111,8 +119,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra def disassemble(stack: ItemStack, instant: Boolean = false) { // Validate the item, never trust Minecraft / other Mods on anything! - if (isItemValidForSlot(0, stack)) { - val ingredients = ItemUtils.getIngredients(stack) + if (canPlaceItem(0, stack)) { + val ingredients = ItemUtils.getIngredients(getLevel.getRecipeManager, stack) DisassemblerTemplates.select(stack) match { case Some(template) => val (stacks, drops) = template.disassemble(stack, ingredients) @@ -132,11 +140,11 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra private def drop(stack: ItemStack) { if (!stack.isEmpty) { - for (side <- EnumFacing.values if stack.getCount > 0) { + for (side <- Direction.values if stack.getCount > 0) { InventoryUtils.insertIntoInventoryAt(stack, BlockPosition(this).offset(side), Some(side.getOpposite)) } if (stack.getCount > 0) { - spawnStackInWorld(stack, Option(EnumFacing.UP)) + spawnStackInWorld(stack, Option(Direction.UP)) } } } @@ -148,55 +156,60 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra private final val TotalTag = Settings.namespace + "total" private final val IsActiveTag = Settings.namespace + "isActive" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) queue.clear() - queue ++= nbt.getTagList(QueueTag, NBT.TAG_COMPOUND). - map((tag: NBTTagCompound) => new ItemStack(tag)) + queue ++= nbt.getList(QueueTag, NBT.TAG_COMPOUND). + map((tag: CompoundNBT) => ItemStack.of(tag)) buffer = nbt.getDouble(BufferTag) totalRequiredEnergy = nbt.getDouble(TotalTag) isActive = queue.nonEmpty } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) nbt.setNewTagList(QueueTag, queue) - nbt.setDouble(BufferTag, buffer) - nbt.setDouble(TotalTag, totalRequiredEnergy) + nbt.putDouble(BufferTag, buffer) + nbt.putDouble(TotalTag, totalRequiredEnergy) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) isActive = nbt.getBoolean(IsActiveTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setBoolean(IsActiveTag, isActive) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putBoolean(IsActiveTag, isActive) } // ----------------------------------------------------------------------- // - override def getSizeInventory = 1 + override def getContainerSize = 1 - override def isItemValidForSlot(i: Int, stack: ItemStack): Boolean = + override def canPlaceItem(i: Int, stack: ItemStack): Boolean = allowDisassembling(stack) && - (((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(stack).nonEmpty) || + (((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(getLevel.getRecipeManager, stack).nonEmpty) || DisassemblerTemplates.select(stack).isDefined) - private def allowDisassembling(stack: ItemStack) = !stack.isEmpty && (!stack.hasTagCompound || !stack.getTagCompound.getBoolean(Settings.namespace + "undisassemblable")) + private def allowDisassembling(stack: ItemStack) = !stack.isEmpty && (!stack.hasTag || !stack.getTag.getBoolean(Settings.namespace + "undisassemblable")) - override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = { - super.setInventorySlotContents(slot, stack) - if (!getWorld.isRemote) { + override def setItem(slot: Int, stack: ItemStack): Unit = { + super.setItem(slot, stack) + if (!getLevel.isClientSide) { disassembleNextInstantly = false } } - override def onSetInventorySlotContents(player: EntityPlayer, slot: Int, stack: ItemStack): Unit = { - if (!getWorld.isRemote) { - disassembleNextInstantly = !stack.isEmpty && slot == 0 && player.capabilities.isCreativeMode + override def onSetInventorySlotContents(player: PlayerEntity, slot: Int, stack: ItemStack): Unit = { + if (!getLevel.isClientSide) { + disassembleNextInstantly = !stack.isEmpty && slot == 0 && player.isCreative } } + + // ----------------------------------------------------------------------- // + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Disassembler(ContainerTypes.DISASSEMBLER, id, playerInventory, this) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala b/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala index d206db2260..00362d76d5 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/DiskDrive.scala @@ -18,19 +18,27 @@ import li.cil.oc.api.network.Node import li.cil.oc.api.network.Visibility import li.cil.oc.common.Slot import li.cil.oc.common.Sound +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.InventoryUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ + +class DiskDrive(selfType: TileEntityType[_ <: DiskDrive]) extends TileEntity(selfType) with traits.Environment + with traits.ComponentInventory with traits.Rotatable with Analyzable with DeviceInfo with INamedContainerProvider { -class DiskDrive extends traits.Environment with traits.ComponentInventory with traits.Rotatable with Analyzable with DeviceInfo { // Used on client side to check whether to render disk activity indicators. var lastAccess = 0L @@ -63,14 +71,14 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t @Callback(doc = "function([velocity:number]):boolean -- Eject the currently present medium from the drive.") def eject(context: Context, args: Arguments): Array[AnyRef] = { val velocity = args.optDouble(0, 0) max 0 min 1 - val ejected = decrStackSize(0, 1) + val ejected = removeItem(0, 1) if (!ejected.isEmpty) { val entity = InventoryUtils.spawnStackInWorld(position, ejected, Option(facing)) if (entity != null) { - val vx = facing.getFrontOffsetX * velocity - val vy = facing.getFrontOffsetY * velocity - val vz = facing.getFrontOffsetZ * velocity - entity.addVelocity(vx, vy, vz) + val vx = facing.getStepX * velocity + val vy = facing.getStepY * velocity + val vz = facing.getStepZ * velocity + entity.push(vx, vy, vz) } result(true) } @@ -80,7 +88,7 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t @Callback(doc = "function(): string -- Return the internal floppy disk address") def media(context: Context, args: Arguments): Array[AnyRef] = { if (filesystemNode.isEmpty) - result(Unit, "drive is empty") + result((), "drive is empty") else result(filesystemNode.head.address) } @@ -88,18 +96,24 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t // ----------------------------------------------------------------------- // // Analyzable - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = filesystemNode.fold(null: Array[Node])(Array(_)) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = filesystemNode.fold(null: Array[Node])(Array(_)) // ----------------------------------------------------------------------- // // IInventory - override def getSizeInventory = 1 + override def getContainerSize = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { case (0, Some(driver)) => driver.slot(stack) == Slot.Floppy case _ => false } + // ----------------------------------------------------------------------- // + // INamedContainerProvider + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.DiskDrive(ContainerTypes.DISK_DRIVE, id, playerInventory, this) + // ----------------------------------------------------------------------- // // ComponentInventory @@ -130,16 +144,16 @@ class DiskDrive extends traits.Environment with traits.ComponentInventory with t private final val DiskTag = Settings.namespace + "disk" - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) - if (nbt.hasKey(DiskTag)) { - setInventorySlotContents(0, new ItemStack(nbt.getCompoundTag(DiskTag))) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) + if (nbt.contains(DiskTag)) { + setItem(0, ItemStack.of(nbt.getCompound(DiskTag))) } } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - if (!items(0).isEmpty) nbt.setNewCompoundTag(DiskTag, items(0).writeToNBT) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + if (!items(0).isEmpty) nbt.setNewCompoundTag(DiskTag, items(0).save) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Geolyzer.scala b/src/main/scala/li/cil/oc/common/tileentity/Geolyzer.scala index f5e8e9bb89..3cddb4f001 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Geolyzer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Geolyzer.scala @@ -1,20 +1,22 @@ package li.cil.oc.common.tileentity import li.cil.oc.server.component -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType -class Geolyzer extends traits.Environment { +class Geolyzer(selfType: TileEntityType[_ <: Geolyzer]) extends TileEntity(selfType) with traits.Environment { val geolyzer = new component.Geolyzer(this) def node = geolyzer.node - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - geolyzer.load(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + geolyzer.loadData(nbt) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - geolyzer.save(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + geolyzer.saveData(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala b/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala index 74ef1c8aa3..718770fb75 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Hologram.scala @@ -13,19 +13,21 @@ import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network._ import li.cil.oc.common.SaveHandler import li.cil.oc.server.{PacketSender => ServerPacketSender} -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraft.util.math.AxisAlignedBB -import net.minecraft.util.math.Vec3d -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.util.math.vector.Vector3d +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable -class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment with Analyzable with traits.RotatableTile with traits.Tickable with DeviceInfo { - def this() = this(0) +class Hologram(selfType: TileEntityType[_ <: Hologram], var tier: Int) extends TileEntity(selfType) with traits.Environment with SidedEnvironment with Analyzable with traits.RotatableTile with traits.Tickable with DeviceInfo { + def this(selfType: TileEntityType[_ <: Hologram]) = this(selfType, 0) val node = api.Network.newNode(this, Visibility.Network). withComponent("hologram"). @@ -57,7 +59,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w var scale = 1.0 // Projection Y position offset - consider adding X,Z later perhaps - var translation = new Vec3d(0, 0, 0) + var translation = new Vector3d(0, 0, 0) // Relative number of lit columns (for energy cost). var litRatio = -1.0 @@ -130,13 +132,13 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing) = toLocal(side) == EnumFacing.DOWN + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction) = toLocal(side) == Direction.DOWN - override def sidedNode(side: EnumFacing) = if (toLocal(side) == EnumFacing.DOWN) node else null + override def sidedNode(side: Direction) = if (toLocal(side) == Direction.DOWN) node else null // Override automatic analyzer implementation for sided environments. - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(node) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(node) // ----------------------------------------------------------------------- // @@ -289,7 +291,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w val ty = math.max(0, math.min(maxTranslation * 2, args.checkDouble(1))) val tz = math.max(-maxTranslation, math.min(maxTranslation, args.checkDouble(2))) - translation = new Vec3d(tx, ty, tz) + translation = new Vector3d(tx, ty, tz) ServerPacketSender.sendHologramOffset(this) null @@ -337,7 +339,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w result(true) } - else result(Unit, "not supported") + else result((), "not supported") } @Callback(doc = """function(speed:number, x:number, y:number, z:number):boolean -- Set the rotation speed of the displayed hologram.""") @@ -356,7 +358,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w result(true) } - else result(Unit, "not supported") + else result((), "not supported") } @Callback(direct = true, doc = "function():number, number, number -- Get the dimension of the x,y,z axes.") @@ -410,7 +412,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w ServerPacketSender.sendHologramValues(this) resetDirtyFlag() } - if (getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (getLevel.getGameTime % Settings.get.tickFrequency == 0) { if (litRatio < 0) this.synchronized { litRatio = 0 for (i <- volume.indices) { @@ -431,9 +433,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w // ----------------------------------------------------------------------- // - override def shouldRenderInPass(pass: Int) = pass == 1 - - override def getMaxRenderDistanceSquared = scale / Settings.get.hologramMaxScaleByTier.max * Settings.get.hologramRenderDistance * Settings.get.hologramRenderDistance + override def getViewDistance = scale / Settings.get.hologramMaxScaleByTier.max * Settings.get.hologramRenderDistance def getFadeStartDistanceSquared = scale / Settings.get.hologramMaxScaleByTier.max * Settings.get.hologramFadeStartDistance * Settings.get.hologramFadeStartDistance @@ -476,9 +476,9 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w private final val RotationSpeedZTag = Settings.namespace + "rotationSpeedZ" private final val HasPowerTag = Settings.namespace + "hasPower" - override def readFromNBTForServer(nbt: NBTTagCompound) { + override def loadForServer(nbt: CompoundNBT) { tier = nbt.getByte(TierTag) max 0 min 1 - super.readFromNBTForServer(nbt) + super.loadForServer(nbt) val tag = SaveHandler.loadNBT(nbt, dataPath) tag.getIntArray(VolumeTag).copyToArray(volume) tag.getIntArray(ColorsTag).map(convertColor).copyToArray(colors) @@ -486,7 +486,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w val tx = nbt.getDouble(OffsetXTag) val ty = nbt.getDouble(OffsetYTag) val tz = nbt.getDouble(OffsetZTag) - translation = new Vec3d(tx, ty, tz) + translation = new Vector3d(tx, ty, tz) rotationAngle = nbt.getFloat(RotationAngleTag) rotationX = nbt.getFloat(RotationXTag) rotationY = nbt.getFloat(RotationYTag) @@ -497,30 +497,30 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w rotationSpeedZ = nbt.getFloat(RotationSpeedZTag) } - override def writeToNBTForServer(nbt: NBTTagCompound) = this.synchronized { - nbt.setByte(TierTag, tier.toByte) - super.writeToNBTForServer(nbt) - SaveHandler.scheduleSave(getWorld, x, z, nbt, dataPath, tag => { - tag.setIntArray(VolumeTag, volume) - tag.setIntArray(ColorsTag, colors.map(convertColor)) + override def saveForServer(nbt: CompoundNBT) = this.synchronized { + nbt.putByte(TierTag, tier.toByte) + super.saveForServer(nbt) + SaveHandler.scheduleSave(getLevel, x, z, nbt, dataPath, tag => { + tag.putIntArray(VolumeTag, volume) + tag.putIntArray(ColorsTag, colors.map(convertColor)) }) - nbt.setDouble(ScaleTag, scale) - nbt.setDouble(OffsetXTag, translation.x) - nbt.setDouble(OffsetYTag, translation.y) - nbt.setDouble(OffsetZTag, translation.z) - nbt.setFloat(RotationAngleTag, rotationAngle) - nbt.setFloat(RotationXTag, rotationX) - nbt.setFloat(RotationYTag, rotationY) - nbt.setFloat(RotationZTag, rotationZ) - nbt.setFloat(RotationSpeedTag, rotationSpeed) - nbt.setFloat(RotationSpeedXTag, rotationSpeedX) - nbt.setFloat(RotationSpeedYTag, rotationSpeedY) - nbt.setFloat(RotationSpeedZTag, rotationSpeedZ) + nbt.putDouble(ScaleTag, scale) + nbt.putDouble(OffsetXTag, translation.x) + nbt.putDouble(OffsetYTag, translation.y) + nbt.putDouble(OffsetZTag, translation.z) + nbt.putFloat(RotationAngleTag, rotationAngle) + nbt.putFloat(RotationXTag, rotationX) + nbt.putFloat(RotationYTag, rotationY) + nbt.putFloat(RotationZTag, rotationZ) + nbt.putFloat(RotationSpeedTag, rotationSpeed) + nbt.putFloat(RotationSpeedXTag, rotationSpeedX) + nbt.putFloat(RotationSpeedYTag, rotationSpeedY) + nbt.putFloat(RotationSpeedZTag, rotationSpeedZ) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) nbt.getIntArray(VolumeTag).copyToArray(volume) nbt.getIntArray(ColorsTag).copyToArray(colors) scale = nbt.getDouble(ScaleTag) @@ -528,7 +528,7 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w val tx = nbt.getDouble(OffsetXTag) val ty = nbt.getDouble(OffsetYTag) val tz = nbt.getDouble(OffsetZTag) - translation = new Vec3d(tx, ty, tz) + translation = new Vector3d(tx, ty, tz) rotationAngle = nbt.getFloat(RotationAngleTag) rotationX = nbt.getFloat(RotationXTag) rotationY = nbt.getFloat(RotationYTag) @@ -539,22 +539,22 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w rotationSpeedZ = nbt.getFloat(RotationSpeedZTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setIntArray(VolumeTag, volume) - nbt.setIntArray(ColorsTag, colors) - nbt.setDouble(ScaleTag, scale) - nbt.setBoolean(HasPowerTag, hasPower) - nbt.setDouble(OffsetXTag, translation.x) - nbt.setDouble(OffsetYTag, translation.y) - nbt.setDouble(OffsetZTag, translation.z) - nbt.setFloat(RotationAngleTag, rotationAngle) - nbt.setFloat(RotationXTag, rotationX) - nbt.setFloat(RotationYTag, rotationY) - nbt.setFloat(RotationZTag, rotationZ) - nbt.setFloat(RotationSpeedTag, rotationSpeed) - nbt.setFloat(RotationSpeedXTag, rotationSpeedX) - nbt.setFloat(RotationSpeedYTag, rotationSpeedY) - nbt.setFloat(RotationSpeedZTag, rotationSpeedZ) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putIntArray(VolumeTag, volume) + nbt.putIntArray(ColorsTag, colors) + nbt.putDouble(ScaleTag, scale) + nbt.putBoolean(HasPowerTag, hasPower) + nbt.putDouble(OffsetXTag, translation.x) + nbt.putDouble(OffsetYTag, translation.y) + nbt.putDouble(OffsetZTag, translation.z) + nbt.putFloat(RotationAngleTag, rotationAngle) + nbt.putFloat(RotationXTag, rotationX) + nbt.putFloat(RotationYTag, rotationY) + nbt.putFloat(RotationZTag, rotationZ) + nbt.putFloat(RotationSpeedTag, rotationSpeed) + nbt.putFloat(RotationSpeedXTag, rotationSpeedX) + nbt.putFloat(RotationSpeedYTag, rotationSpeedY) + nbt.putFloat(RotationSpeedZTag, rotationSpeedZ) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala b/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala index 1ffbfe301a..bf6d1e9f4a 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala @@ -6,14 +6,16 @@ import li.cil.oc.api import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network.SidedEnvironment import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -class Keyboard extends traits.Environment with traits.Rotatable with traits.ImmibisMicroblock with SidedEnvironment with Analyzable { - override def validFacings = EnumFacing.values +class Keyboard(selfType: TileEntityType[_ <: Keyboard]) extends TileEntity(selfType) with traits.Environment with traits.Rotatable with traits.ImmibisMicroblock with SidedEnvironment with Analyzable { + override def validFacings = Direction.values val keyboard = { val keyboardItem = api.Items.get(Constants.BlockName.Keyboard).createItemStack(1) @@ -22,18 +24,18 @@ class Keyboard extends traits.Environment with traits.Rotatable with traits.Immi override def node = keyboard.node - def hasNodeOnSide(side: EnumFacing) : Boolean = + def hasNodeOnSide(side: Direction) : Boolean = side != facing && (isOnWall || side.getOpposite != forward) // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing) = hasNodeOnSide(side) + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction) = hasNodeOnSide(side) - override def sidedNode(side: EnumFacing) = if (hasNodeOnSide(side)) node else null + override def sidedNode(side: Direction) = if (hasNodeOnSide(side)) node else null // Override automatic analyzer implementation for sided environments. - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(node) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(node) // ----------------------------------------------------------------------- // @@ -41,23 +43,23 @@ class Keyboard extends traits.Environment with traits.Rotatable with traits.Immi private final val KeyboardTag = Settings.namespace + "keyboard" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) if (isServer) { - keyboard.load(nbt.getCompoundTag(KeyboardTag)) + keyboard.loadData(nbt.getCompound(KeyboardTag)) } } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) if (isServer) { - nbt.setNewCompoundTag(KeyboardTag, keyboard.save) + nbt.setNewCompoundTag(KeyboardTag, keyboard.saveData) } } // ----------------------------------------------------------------------- // - private def isOnWall = facing != EnumFacing.UP && facing != EnumFacing.DOWN + private def isOnWall = facing != Direction.UP && facing != Direction.DOWN - private def forward = if (isOnWall) EnumFacing.UP else yaw + private def forward = if (isOnWall) Direction.UP else yaw } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala b/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala index b3c256206f..84b09653e7 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.tileentity import java.util +import java.util.function.Consumer import li.cil.oc.Constants import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute @@ -19,18 +20,21 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.ISidedInventory import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.JavaConverters.asJavaIterable +import scala.collection.convert.ImplicitConversionsToJava._ -class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.Computer with ISidedInventory with internal.Microcontroller with DeviceInfo { +class Microcontroller(selfType: TileEntityType[_ <: Microcontroller]) extends TileEntity(selfType) with traits.PowerAcceptor with traits.Hub with traits.Computer with ISidedInventory with internal.Microcontroller with DeviceInfo { val info = new MicrocontrollerData() override def node = null @@ -60,31 +64,31 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C DeviceAttribute.Description -> "Microcontroller", DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, DeviceAttribute.Product -> "Cubicle", - DeviceAttribute.Capacity -> getSizeInventory.toString + DeviceAttribute.Capacity -> getContainerSize.toString ) override def getDeviceInfo: util.Map[String, String] = deviceInfo // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing): Boolean = side != facing + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction): Boolean = side != facing - override def sidedNode(side: EnumFacing): Node = if (side != facing) super.sidedNode(side) else null + override def sidedNode(side: Direction): Node = if (side != facing) super.sidedNode(side) else null - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing): Boolean = side != facing + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction): Boolean = side != facing - override protected def connector(side: EnumFacing) = Option(if (side != facing) snooperNode else null) + override protected def connector(side: Direction) = Option(if (side != facing) snooperNode else null) override def energyThroughput: Double = Settings.get.caseRate(Tier.One) // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { super.onAnalyze(player, side, hitX, hitY, hitZ) if (side != facing) - Array(componentNodes(side.getIndex)) + Array(componentNodes(side.get3DDataValue)) else Array(machine.node) } @@ -133,8 +137,8 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C super.updateEntity() // Pump energy into the internal network. - if (isServer && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { - for (side <- EnumFacing.values if side != facing) { + if (isServer && getLevel.getGameTime % Settings.get.tickFrequency == 0) { + for (side <- Direction.values if side != facing) { sidedNode(side) match { case connector: Connector => val demand = snooperNode.globalBufferSize - snooperNode.globalBuffer @@ -192,7 +196,7 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C override def onMessage(message: Message): Unit = { if (message.name == "network.message" && message.source.network == snooperNode.network) { - for (side <- EnumFacing.values if outputSides(side.ordinal) && side != facing) { + for (side <- Direction.values if outputSides(side.ordinal) && side != facing) { sidedNode(side).sendToReachable(message.name, message.data: _*) } } @@ -205,44 +209,44 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C private final val ComponentNodesTag = Settings.namespace + "componentNodes" private final val SnooperTag = Settings.namespace + "snooper" - override def readFromNBTForServer(nbt: NBTTagCompound) { + override def loadForServer(nbt: CompoundNBT) { // Load info before inventory and such, to avoid initializing components // to empty inventory. - info.load(nbt.getCompoundTag(InfoTag)) + info.loadData(nbt.getCompound(InfoTag)) nbt.getBooleanArray(OutputsTag) - nbt.getTagList(ComponentNodesTag, NBT.TAG_COMPOUND).toArray[NBTTagCompound]. + nbt.getList(ComponentNodesTag, NBT.TAG_COMPOUND).toTagArray[CompoundNBT]. zipWithIndex.foreach { - case (tag, index) => componentNodes(index).load(tag) + case (tag, index) => componentNodes(index).loadData(tag) } - snooperNode.load(nbt.getCompoundTag(SnooperTag)) - super.readFromNBTForServer(nbt) + snooperNode.loadData(nbt.getCompound(SnooperTag)) + super.loadForServer(nbt) api.Network.joinNewNetwork(machine.node) machine.node.connect(snooperNode) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setNewCompoundTag(InfoTag, info.save) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + nbt.setNewCompoundTag(InfoTag, info.saveData) nbt.setBooleanArray(OutputsTag, outputSides) nbt.setNewTagList(ComponentNodesTag, componentNodes.map { case node: Node => - val tag = new NBTTagCompound() - node.save(tag) + val tag = new CompoundNBT() + node.saveData(tag) tag - case _ => new NBTTagCompound() + case _ => new CompoundNBT() }) - nbt.setNewCompoundTag(SnooperTag, snooperNode.save) + nbt.setNewCompoundTag(SnooperTag, snooperNode.saveData) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound) { - info.load(nbt.getCompoundTag(InfoTag)) - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT) { + info.loadData(nbt.getCompound(InfoTag)) + super.loadForClient(nbt) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setNewCompoundTag(InfoTag, info.save) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.setNewCompoundTag(InfoTag, info.saveData) } // ----------------------------------------------------------------------- // @@ -251,38 +255,47 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C override def updateItems(slot: Int, stack: ItemStack): Unit = info.components(slot) = stack - override def getSizeInventory: Int = info.components.length + override def getContainerSize: Int = info.components.length - override def isItemValidForSlot(slot: Int, stack: ItemStack) = false + override def canPlaceItem(slot: Int, stack: ItemStack) = false // Nope. - override def setInventorySlotContents(slot: Int, stack: ItemStack) {} + override def setItem(slot: Int, stack: ItemStack) {} // Nope. - override def decrStackSize(slot: Int, amount: Int) = ItemStack.EMPTY + override def removeItem(slot: Int, amount: Int) = ItemStack.EMPTY // Nope. - override def removeStackFromSlot(slot: Int) = ItemStack.EMPTY + override def removeItemNoUpdate(slot: Int) = ItemStack.EMPTY // Nope. - override def canExtractItem(slot: Int, stack: ItemStack, side: EnumFacing) = false + override def canTakeItemThroughFace(slot: Int, stack: ItemStack, side: Direction) = false - override def canInsertItem(slot: Int, stack: ItemStack, side: EnumFacing) = false + override def canPlaceItemThroughFace(slot: Int, stack: ItemStack, side: Direction) = false - override def getSlotsForFace(side: EnumFacing): Array[Int] = Array() + override def getSlotsForFace(side: Direction): Array[Int] = Array() // For hotswapping EEPROMs. def changeEEPROM(newEeprom: ItemStack): StackOption = { val oldEepromIndex = info.components.indexWhere(api.Items.get(_) == api.Items.get(Constants.ItemName.EEPROM)) if (oldEepromIndex >= 0) { val oldEeprom = info.components(oldEepromIndex) - super.setInventorySlotContents(oldEepromIndex, newEeprom) + super.setItem(oldEepromIndex, newEeprom) SomeStack(oldEeprom) } else { - assert(info.components(getSizeInventory - 1).isEmpty) - super.setInventorySlotContents(getSizeInventory - 1, newEeprom) + assert(info.components(getContainerSize - 1).isEmpty) + super.setItem(getContainerSize - 1, newEeprom) EmptyStack } } + + // Uses the loot system, so still nope. + override def forAllLoot(dst: Consumer[ItemStack]) = () + + // Nope. + override def dropSlot(slot: Int, count: Int = getMaxStackSize, direction: Option[Direction]) = false + + // Nope. + override def dropAllSlots() = () } diff --git a/src/main/scala/li/cil/oc/common/tileentity/MotionSensor.scala b/src/main/scala/li/cil/oc/common/tileentity/MotionSensor.scala index 9d09d5d0d5..0f6218e8d2 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/MotionSensor.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/MotionSensor.scala @@ -2,9 +2,11 @@ package li.cil.oc.common.tileentity import li.cil.oc.api.network.Node import li.cil.oc.server.component -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType -class MotionSensor extends traits.Environment with traits.Tickable { +class MotionSensor(selfType: TileEntityType[_ <: MotionSensor]) extends TileEntity(selfType) with traits.Environment with traits.Tickable { val motionSensor = new component.MotionSensor(this) def node: Node = motionSensor.node @@ -16,13 +18,13 @@ class MotionSensor extends traits.Environment with traits.Tickable { } } - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - motionSensor.load(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + motionSensor.loadData(nbt) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - motionSensor.save(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + motionSensor.saveData(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala b/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala index d7d8e264e0..ccc3b44d23 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala @@ -10,17 +10,20 @@ import li.cil.oc.api.network.{Node, Visibility} import li.cil.oc.common.EventHandler import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs import li.cil.oc.server.{PacketSender => ServerPacketSender} -import net.minecraft.init.SoundEvents -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import li.cil.oc.util.RotationHelper +import net.minecraft.util.SoundEvents +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraft.util.SoundCategory -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable -class NetSplitter extends traits.Environment with traits.OpenSides with traits.RedstoneAware with api.network.SidedEnvironment with DeviceInfo { +class NetSplitter(selfType: TileEntityType[_ <: NetSplitter]) extends TileEntity(selfType) with traits.Environment with traits.OpenSides with traits.RedstoneAware with api.network.SidedEnvironment with DeviceInfo { private lazy val deviceInfo: util.Map[String, String] = Map( DeviceAttribute.Class -> DeviceClass.Network, DeviceAttribute.Description -> "Ethernet controller", @@ -40,9 +43,9 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R var isInverted = false - override def isSideOpen(side: EnumFacing): Boolean = if (isInverted) !super.isSideOpen(side) else super.isSideOpen(side) + override def isSideOpen(side: Direction): Boolean = if (isInverted) !super.isSideOpen(side) else super.isSideOpen(side) - override def setSideOpen(side: EnumFacing, value: Boolean) { + override def setSideOpen(side: Direction, value: Boolean) { val previous = isSideOpen(side) super.setSideOpen(side, value) if (previous != isSideOpen(side)) { @@ -50,21 +53,21 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R node.remove() api.Network.joinOrCreateNetwork(this) ServerPacketSender.sendNetSplitterState(this) - getWorld.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, getWorld.rand.nextFloat() * 0.25f + 0.7f) - getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false) + getLevel.playSound(null, getBlockPos, SoundEvents.PISTON_EXTEND, SoundCategory.BLOCKS, 0.5f, getLevel.random.nextFloat() * 0.25f + 0.7f) + getLevel.updateNeighborsAt(getBlockPos, getBlockState.getBlock) } else { - getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) } } } // ----------------------------------------------------------------------- // - override def sidedNode(side: EnumFacing): Node = if (isSideOpen(side)) node else null + override def sidedNode(side: Direction): Node = if (isSideOpen(side)) node else null - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing): Boolean = isSideOpen(side) + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction): Boolean = isSideOpen(side) // ----------------------------------------------------------------------- // @@ -84,10 +87,10 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R node.remove() api.Network.joinOrCreateNetwork(this) ServerPacketSender.sendNetSplitterState(this) - getWorld.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5f, getWorld.rand.nextFloat() * 0.25f + 0.7f) + getLevel.playSound(null, getBlockPos, SoundEvents.PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5f, getLevel.random.nextFloat() * 0.25f + 0.7f) } else { - getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) } } } @@ -97,37 +100,37 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R private final val IsInvertedTag = Settings.namespace + "isInverted" private final val OpenSidesTag = Settings.namespace + "openSides" - override def readFromNBTForServer(nbt: NBTTagCompound): Unit = { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT): Unit = { + super.loadForServer(nbt) isInverted = nbt.getBoolean(IsInvertedTag) } - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - super.writeToNBTForServer(nbt) - nbt.setBoolean(IsInvertedTag, isInverted) + override def saveForServer(nbt: CompoundNBT): Unit = { + super.saveForServer(nbt) + nbt.putBoolean(IsInvertedTag, isInverted) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound): Unit = { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT): Unit = { + super.loadForClient(nbt) isInverted = nbt.getBoolean(IsInvertedTag) } - override def writeToNBTForClient(nbt: NBTTagCompound): Unit = { - super.writeToNBTForClient(nbt) - nbt.setBoolean(IsInvertedTag, isInverted) + override def saveForClient(nbt: CompoundNBT): Unit = { + super.saveForClient(nbt) + nbt.putBoolean(IsInvertedTag, isInverted) } // component api def currentStatus(): mutable.Map[Int, Boolean] = { val openStatus = mutable.Map[Int, Boolean]() - for (side <- EnumFacing.VALUES) { + for (side <- Direction.values) { openStatus += side.ordinal() -> isSideOpen(side) } openStatus } - def setSide(side: EnumFacing, state: Boolean): Boolean = { + def setSide(side: Direction, state: Boolean): Boolean = { val previous = isSideOpen(side) // isSideOpen uses inverter setSideOpen(side, if (isInverted) !state else state) // but setSideOpen does not previous != state @@ -137,7 +140,7 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R def setSides(context: Context, args: Arguments): Array[AnyRef] = { val settings = args.checkTable(0) val previous = currentStatus() - for (side <- EnumFacing.VALUES) { + for (side <- Direction.values) { val ordinal = side.ordinal() val value = if (settings.containsKey(ordinal)) { settings.get(ordinal) match { @@ -156,8 +159,8 @@ class NetSplitter extends traits.Environment with traits.OpenSides with traits.R def setSideHelper(args: Arguments, value: Boolean): Array[AnyRef] = { val sideIndex = args.checkInteger(0) if (sideIndex < 0 || sideIndex > 5) - return result(Unit, "invalid direction") - val side = EnumFacing.getFront(sideIndex) + return result((), "invalid direction") + val side = Direction.from3DDataValue(sideIndex) result(setSide(side, value)) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/PowerConverter.scala b/src/main/scala/li/cil/oc/common/tileentity/PowerConverter.scala index cf6ad933b8..598fc534ef 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/PowerConverter.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/PowerConverter.scala @@ -9,13 +9,15 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.driver.DeviceInfo import li.cil.oc.api.network._ -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ -class PowerConverter extends traits.PowerAcceptor with traits.Environment with traits.NotAnalyzable with DeviceInfo { +class PowerConverter(selfType: TileEntityType[_ <: PowerConverter]) extends TileEntity(selfType) with traits.PowerAcceptor with traits.Environment with traits.NotAnalyzable with DeviceInfo { val node = api.Network.newNode(this, Visibility.None). withConnector(Settings.get.bufferConverter). create() @@ -30,10 +32,10 @@ class PowerConverter extends traits.PowerAcceptor with traits.Environment with t override def getDeviceInfo: util.Map[String, String] = deviceInfo - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing) = true + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction) = true - override protected def connector(side: EnumFacing) = Option(node) + override protected def connector(side: Direction) = Option(node) override def energyThroughput = Settings.get.powerConverterRate } diff --git a/src/main/scala/li/cil/oc/common/tileentity/PowerDistributor.scala b/src/main/scala/li/cil/oc/common/tileentity/PowerDistributor.scala index 12984473d9..83a5716dd0 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/PowerDistributor.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/PowerDistributor.scala @@ -4,13 +4,15 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.network._ import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -class PowerDistributor extends traits.Environment with traits.PowerBalancer with traits.NotAnalyzable { +class PowerDistributor(selfType: TileEntityType[_ <: PowerDistributor]) extends TileEntity(selfType) with traits.Environment with traits.PowerBalancer with traits.NotAnalyzable { val node = null private val nodes = Array.fill(6)(api.Network.newNode(this, Visibility.None). @@ -21,30 +23,30 @@ class PowerDistributor extends traits.Environment with traits.PowerBalancer with // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing) = true + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction) = true - override def sidedNode(side: EnumFacing): Connector = nodes(side.ordinal) + override def sidedNode(side: Direction): Connector = nodes(side.ordinal) // ----------------------------------------------------------------------- // private final val ConnectorTag = Settings.namespace + "connector" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - nbt.getTagList(ConnectorTag, NBT.TAG_COMPOUND).toArray[NBTTagCompound]. + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + nbt.getList(ConnectorTag, NBT.TAG_COMPOUND).toTagArray[CompoundNBT]. zipWithIndex.foreach { - case (tag, index) => nodes(index).load(tag) + case (tag, index) => nodes(index).loadData(tag) } } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) // Side check for Waila (and other mods that may call this client side). if (isServer) { nbt.setNewTagList(ConnectorTag, nodes.map(connector => { - val connectorNbt = new NBTTagCompound() - connector.save(connectorNbt) + val connectorNbt = new CompoundNBT() + connector.saveData(connectorNbt) connectorNbt })) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Print.scala b/src/main/scala/li/cil/oc/common/tileentity/Print.scala index 1214010bc7..6123a0a640 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Print.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Print.scala @@ -6,104 +6,51 @@ import com.google.common.base.Strings import li.cil.oc.Constants import li.cil.oc.Settings import li.cil.oc.api +import li.cil.oc.common.block.{Print => PrintBlock} import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs import li.cil.oc.util.ExtendedAABB import li.cil.oc.util.ExtendedAABB._ import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.init.SoundEvents -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util._ -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.util.SoundEvents +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraft.util.SoundCategory import net.minecraft.util.math.BlockPos import net.minecraft.util.math.RayTraceResult -import net.minecraft.util.math.Vec3d -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly -import scala.collection.convert.WrapAsJava._ - -class Print(val canToggle: Option[() => Boolean], val scheduleUpdate: Option[Int => Unit], val onStateChange: Option[() => Unit]) extends traits.TileEntity with traits.RedstoneAware with traits.RotatableTile { - def this() = this(None, None, None) - def this(canToggle: () => Boolean, scheduleUpdate: Int => Unit, onStateChange: () => Unit) = this(Option(canToggle), Option(scheduleUpdate), Option(onStateChange)) +import net.minecraft.util.math.shapes.IBooleanFunction +import net.minecraft.util.math.shapes.VoxelShape +import net.minecraft.util.math.shapes.VoxelShapes +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn +import net.minecraftforge.client.model.data.IModelData +import net.minecraftforge.client.model.data.ModelProperty +import scala.collection.Iterable +import scala.collection.convert.ImplicitConversionsToJava._ + +class Print(selfType: TileEntityType[_ <: Print], val canToggle: Option[() => Boolean], val scheduleUpdate: Option[Int => Unit], val onStateChange: Option[() => Unit]) + extends TileEntity(selfType) with traits.TileEntity with traits.RedstoneAware with traits.RotatableTile with IModelData { + + def this(selfType: TileEntityType[_ <: Print]) = this(selfType, None, None, None) + def this(selfType: TileEntityType[_ <: Print], canToggle: () => Boolean, scheduleUpdate: Int => Unit, onStateChange: () => Unit) = + this(selfType, Option(canToggle), Option(scheduleUpdate), Option(onStateChange)) _isOutputEnabled = true val data = new PrintData() - var boundsOff = ExtendedAABB.unitBounds - var boundsOn = ExtendedAABB.unitBounds + var shapeOff = VoxelShapes.block + var shapeOn = VoxelShapes.block var state = false - def bounds = if (state) boundsOn else boundsOff + def shape = if (state) shapeOn else shapeOff def noclip = if (state) data.noclipOn else data.noclipOff def shapes = if (state) data.stateOn else data.stateOff - def isSideSolid(side: EnumFacing): Boolean = { - for (shape <- shapes if !Strings.isNullOrEmpty(shape.texture)) { - val bounds = shape.bounds.rotateTowards(facing) - val fullX = bounds.minX == 0 && bounds.maxX == 1 - val fullY = bounds.minY == 0 && bounds.maxY == 1 - val fullZ = bounds.minZ == 0 && bounds.maxZ == 1 - if (side match { - case EnumFacing.DOWN => bounds.minY == 0 && fullX && fullZ - case EnumFacing.UP => bounds.maxY == 1 && fullX && fullZ - case EnumFacing.NORTH => bounds.minZ == 0 && fullX && fullY - case EnumFacing.SOUTH => bounds.maxZ == 1 && fullX && fullY - case EnumFacing.WEST => bounds.minX == 0 && fullY && fullZ - case EnumFacing.EAST => bounds.maxX == 1 && fullY && fullZ - case _ => false - }) return true - } - false - } - - def addCollisionBoxesToList(mask: AxisAlignedBB, list: util.List[AxisAlignedBB], pos: BlockPos = BlockPos.ORIGIN): Unit = { - if (!noclip) { - if (shapes.isEmpty) { - val unitBounds = new AxisAlignedBB(0, 0, 0, 1, 1, 1).offset(pos) - if (mask == null || unitBounds.intersects(mask)) { - list.add(unitBounds) - } - } else { - for (shape <- shapes) { - val bounds = shape.bounds.rotateTowards(facing).offset(pos) - if (mask == null || bounds.intersects(mask)) { - list.add(bounds) - } - } - } - } - } - - def rayTrace(start: Vec3d, end: Vec3d, pos: BlockPos = BlockPos.ORIGIN): RayTraceResult = { - var closestDistance = Double.PositiveInfinity - var closest: Option[RayTraceResult] = None - if (shapes.isEmpty) { - val bounds = new AxisAlignedBB(0, 0, 0, 1, 1, 1).offset(pos) - val hit = bounds.calculateIntercept(start, end) - if (hit != null) { - val distance = hit.hitVec.distanceTo(start) - if (distance < closestDistance) { - closestDistance = distance - closest = Option(hit) - } - } - } else { - for (shape <- shapes) { - val bounds = shape.bounds.rotateTowards(facing).offset(pos) - val hit = bounds.calculateIntercept(start, end) - if (hit != null) { - val distance = hit.hitVec.distanceTo(start) - if (distance < closestDistance) { - closestDistance = distance - closest = Option(hit) - } - } - } - } - closest.map(hit => new RayTraceResult(hit.hitVec, hit.sideHit, pos)).orNull - } - def activate(): Boolean = { if (data.hasActiveState) { if (!state || !data.isButtonMode) { @@ -116,7 +63,7 @@ class Print(val canToggle: Option[() => Boolean], val scheduleUpdate: Option[Int private def buildValueSet(value: Int): util.Map[AnyRef, AnyRef] = { val map: util.Map[AnyRef, AnyRef] = new util.HashMap[AnyRef, AnyRef]() - EnumFacing.values.foreach { + Direction.values.foreach { side => map.put(new java.lang.Integer(side.ordinal), new java.lang.Integer(value)) } map @@ -125,28 +72,33 @@ class Print(val canToggle: Option[() => Boolean], val scheduleUpdate: Option[Int def toggleState(): Unit = { if (canToggle.fold(true)(_.apply())) { state = !state - world.playSound(null, x + 0.5, y + 0.5, z + 0.5, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, if (state) 0.6F else 0.5F) - world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + getLevel.playSound(null, getBlockPos, SoundEvents.LEVER_CLICK, SoundCategory.BLOCKS, 0.3F, if (state) 0.6F else 0.5F) + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) updateRedstone() if (state && data.isButtonMode) { - val block = api.Items.get(Constants.BlockName.Print).block() - val delay = block.tickRate(world) + val block = api.Items.get(Constants.BlockName.Print).block().asInstanceOf[PrintBlock] + val delay = block.tickRate(getLevel) scheduleUpdate match { case Some(callback) => callback(delay) - case _ => world.scheduleUpdate(getPos, block, delay) + case _ if !getLevel.isClientSide => getLevel.asInstanceOf[ServerWorld].getBlockTicks.scheduleTick(getBlockPos, block, delay) + case _ => } } onStateChange.foreach(_.apply()) } } - def updateBounds(): Unit = { - boundsOff = data.stateOff.drop(1).foldLeft(data.stateOff.headOption.fold(ExtendedAABB.unitBounds)(_.bounds))((a, b) => a.union(b.bounds)) - if (boundsOff.volume == 0) boundsOff = ExtendedAABB.unitBounds - else boundsOff = boundsOff.rotateTowards(facing) - boundsOn = data.stateOn.drop(1).foldLeft(data.stateOn.headOption.fold(ExtendedAABB.unitBounds)(_.bounds))((a, b) => a.union(b.bounds)) - if (boundsOn.volume == 0) boundsOn = ExtendedAABB.unitBounds - else boundsOn = boundsOn.rotateTowards(facing) + private def convertShape(state: Iterable[PrintData.Shape]): VoxelShape = if (!state.isEmpty) { + state.foldLeft(VoxelShapes.empty)((curr, s) => { + val voxel = VoxelShapes.create(s.bounds.rotateTowards(facing)) + VoxelShapes.joinUnoptimized(curr, voxel, IBooleanFunction.OR) + }).optimize() + } + else VoxelShapes.block + + def updateShape(): Unit = { + shapeOff = convertShape(data.stateOff) + shapeOn = convertShape(data.stateOn) } def updateRedstone(): Unit = { @@ -164,50 +116,66 @@ class Print(val canToggle: Option[() => Boolean], val scheduleUpdate: Option[Int override protected def onRotationChanged(): Unit = { super.onRotationChanged() - updateBounds() + updateShape() } // ----------------------------------------------------------------------- // private final val DataTag = Settings.namespace + "data" + @Deprecated private final val DataTagCompat = "data" private final val StateTag = Settings.namespace + "state" + @Deprecated private final val StateTagCompat = "state" - override def readFromNBTForServer(nbt: NBTTagCompound): Unit = { - super.readFromNBTForServer(nbt) - if (nbt.hasKey(DataTagCompat)) - data.load(nbt.getCompoundTag(DataTagCompat)) + override def loadForServer(nbt: CompoundNBT): Unit = { + super.loadForServer(nbt) + if (nbt.contains(DataTagCompat)) + data.loadData(nbt.getCompound(DataTagCompat)) else - data.load(nbt.getCompoundTag(DataTag)) - if (nbt.hasKey(StateTagCompat)) + data.loadData(nbt.getCompound(DataTag)) + if (nbt.contains(StateTagCompat)) state = nbt.getBoolean(StateTagCompat) else state = nbt.getBoolean(StateTag) - updateBounds() + updateShape() } - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - super.writeToNBTForServer(nbt) - nbt.setNewCompoundTag(DataTag, data.save) - nbt.setBoolean(StateTag, state) + override def saveForServer(nbt: CompoundNBT): Unit = { + super.saveForServer(nbt) + nbt.setNewCompoundTag(DataTag, data.saveData) + nbt.putBoolean(StateTag, state) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound): Unit = { - super.readFromNBTForClient(nbt) - data.load(nbt.getCompoundTag(DataTag)) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT): Unit = { + super.loadForClient(nbt) + data.loadData(nbt.getCompound(DataTag)) state = nbt.getBoolean(StateTag) - updateBounds() - if (world != null) { - world.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) - if (data.emitLight) world.checkLight(getPos) + updateShape() + if (getLevel != null) { + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) + if (data.emitLight) getLevel.getLightEngine.checkBlock(getBlockPos) } } - override def writeToNBTForClient(nbt: NBTTagCompound): Unit = { - super.writeToNBTForClient(nbt) - nbt.setNewCompoundTag(DataTag, data.save) - nbt.setBoolean(StateTag, state) + override def saveForClient(nbt: CompoundNBT): Unit = { + super.saveForClient(nbt) + nbt.setNewCompoundTag(DataTag, data.saveData) + nbt.putBoolean(StateTag, state) } + + // ----------------------------------------------------------------------- // + + @Deprecated + override def getModelData() = this + + @Deprecated + override def hasProperty(prop: ModelProperty[_]) = false + + @Deprecated + override def getData[T](prop: ModelProperty[T]): T = null.asInstanceOf[T] + + @Deprecated + override def setData[T](prop: ModelProperty[T], value: T): T = null.asInstanceOf[T] } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Printer.scala b/src/main/scala/li/cil/oc/common/tileentity/Printer.scala index f60e2e2d45..04a8d8034a 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Printer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Printer.scala @@ -13,22 +13,31 @@ import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.api.network._ import li.cil.oc.api.util.StateAware +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.item.data.PrintData import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory.ISidedInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraft.util.math.AxisAlignedBB -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ + +class Printer(selfType: TileEntityType[_ <: Printer]) extends TileEntity(selfType) with traits.Environment with traits.Inventory with traits.Rotatable + with SidedEnvironment with traits.StateAware with traits.Tickable with ISidedInventory with DeviceInfo with INamedContainerProvider { -class Printer extends traits.Environment with traits.Inventory with traits.Rotatable with SidedEnvironment with traits.StateAware with traits.Tickable with ISidedInventory with DeviceInfo { val node: ComponentConnector = api.Network.newNode(this, Visibility.Network). withComponent("printer3d"). withConnector(Settings.get.bufferConverter). @@ -61,10 +70,10 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing): Boolean = side != EnumFacing.UP + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction): Boolean = side != Direction.UP - override def sidedNode(side: EnumFacing): ComponentConnector = if (side != EnumFacing.UP) node else null + override def sidedNode(side: Direction): ComponentConnector = if (side != Direction.UP) node else null override def getCurrentState: util.EnumSet[StateAware.State] = { if (isPrinting) util.EnumSet.of(api.util.StateAware.State.IsWorking) @@ -170,7 +179,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat @Callback(doc = """function(minX:number, minY:number, minZ:number, maxX:number, maxY:number, maxZ:number, texture:string[, state:boolean=false][,tint:number]) -- Adds a shape to the printers configuration, optionally specifying whether it is for the off or on state.""") def addShape(context: Context, args: Arguments): Array[Object] = { if (data.stateOff.size > Settings.get.maxPrintComplexity || data.stateOn.size > Settings.get.maxPrintComplexity) { - return result(Unit, "model too complex") + return result((), "model too complex") } val minX = (args.checkInteger(0) max 0 min 16) / 16f val minY = (args.checkInteger(1) max 0 min 16) / 16f @@ -197,7 +206,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat texture, tint) isActive = false // Needs committing. - getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) result(true) } @@ -211,7 +220,7 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat @Callback(doc = """function([count:number]):boolean -- Commit and begin printing the current configuration.""") def commit(context: Context, args: Arguments): Array[Object] = { if (!canPrint) { - return result(Unit, "model invalid") + return result((), "model invalid") } limit = (args.optDouble(0, 1) max 0 min Integer.MAX_VALUE).toInt isActive = limit > 0 @@ -235,9 +244,9 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat } def canMergeOutput = { - val presentStack = getStackInSlot(slotOutput) + val presentStack = getItem(slotOutput) val outputStack = data.createItemStack() - presentStack.isEmpty || (presentStack.isItemEqual(outputStack) && ItemStack.areItemStackTagsEqual(presentStack, outputStack)) + presentStack.isEmpty || (presentStack.sameItem(outputStack) && ItemStack.tagMatches(presentStack, outputStack)) } if (isActive && output.isEmpty && canMergeOutput) { @@ -265,13 +274,13 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat val have = want + (if (Settings.get.ignorePower) 0 else node.changeBuffer(-want)) requiredEnergy -= have if (requiredEnergy <= 0) { - val result = getStackInSlot(slotOutput) + val result = getItem(slotOutput) if (result.isEmpty) { - setInventorySlotContents(slotOutput, output.get) + setItem(slotOutput, output.get) } else if (result.getCount < result.getMaxStackSize && canMergeOutput /* Should never fail, but just in case... */ ) { result.grow(1) - markDirty() + setChanged() } else { return @@ -282,21 +291,21 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat ServerPacketSender.sendPrinting(this, have > 0.5 && output.isDefined) } - val inputValue = PrintData.materialValue(getStackInSlot(slotMaterial)) + val inputValue = PrintData.materialValue(getItem(slotMaterial)) if (inputValue > 0 && maxAmountMaterial - amountMaterial >= inputValue) { - val material = decrStackSize(slotMaterial, 1) + val material = removeItem(slotMaterial, 1) if (material != null) { amountMaterial += inputValue } } - val inkValue = PrintData.inkValue(getStackInSlot(slotInk)) + val inkValue = PrintData.inkValue(getItem(slotInk)) if (inkValue > 0 && maxAmountInk - amountInk >= inkValue) { - val material = decrStackSize(slotInk, 1) + val material = removeItem(slotInk, 1) if (material != null) { amountInk += inkValue - if (material.getItem.hasContainerItem(material)) { - setInventorySlotContents(slotInk, material.getItem.getContainerItem(material)) + if (material.hasContainerItem()) { + setItem(slotInk, material.getContainerItem()) } } } @@ -313,15 +322,15 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat private final val TotalTag = Settings.namespace + "total" private final val RemainingTag = Settings.namespace + "remaining" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - amountMaterial = nbt.getInteger(AmountMaterialTag) - amountInk = nbt.getInteger(AmountInkTag) - data.load(nbt.getCompoundTag(DataTag)) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + amountMaterial = nbt.getInt(AmountMaterialTag) + amountInk = nbt.getInt(AmountInkTag) + data.loadData(nbt.getCompound(DataTag)) isActive = nbt.getBoolean(IsActiveTag) - limit = nbt.getInteger(LimitTag) - if (nbt.hasKey(OutputTag)) { - output = StackOption(new ItemStack(nbt.getCompoundTag(OutputTag))) + limit = nbt.getInt(LimitTag) + if (nbt.contains(OutputTag)) { + output = StackOption(ItemStack.of(nbt.getCompound(OutputTag))) } else { output = EmptyStack @@ -330,36 +339,36 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat requiredEnergy = nbt.getDouble(RemainingTag) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setInteger(AmountMaterialTag, amountMaterial) - nbt.setInteger(AmountInkTag, amountInk) - nbt.setNewCompoundTag(DataTag, data.save) - nbt.setBoolean(IsActiveTag, isActive) - nbt.setInteger(LimitTag, limit) - output.foreach(stack => nbt.setNewCompoundTag(OutputTag, stack.writeToNBT)) - nbt.setDouble(TotalTag, totalRequiredEnergy) - nbt.setDouble(RemainingTag, requiredEnergy) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + nbt.putInt(AmountMaterialTag, amountMaterial) + nbt.putInt(AmountInkTag, amountInk) + nbt.setNewCompoundTag(DataTag, data.saveData) + nbt.putBoolean(IsActiveTag, isActive) + nbt.putInt(LimitTag, limit) + output.foreach(stack => nbt.setNewCompoundTag(OutputTag, stack.save)) + nbt.putDouble(TotalTag, totalRequiredEnergy) + nbt.putDouble(RemainingTag, requiredEnergy) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) - data.load(nbt.getCompoundTag(DataTag)) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) + data.loadData(nbt.getCompound(DataTag)) requiredEnergy = nbt.getDouble(RemainingTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setNewCompoundTag(DataTag, data.save) - nbt.setDouble(RemainingTag, requiredEnergy) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.setNewCompoundTag(DataTag, data.saveData) + nbt.putDouble(RemainingTag, requiredEnergy) } // ----------------------------------------------------------------------- // - override def getSizeInventory = 3 + override def getContainerSize = 3 - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = if (slot == slotMaterial) PrintData.materialValue(stack) > 0 else if (slot == slotInk) @@ -368,9 +377,14 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat // ----------------------------------------------------------------------- // - override def getSlotsForFace(side: EnumFacing): Array[Int] = Array(slotMaterial, slotInk, slotOutput) + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Printer(ContainerTypes.PRINTER, id, playerInventory, this) + + // ----------------------------------------------------------------------- // + + override def getSlotsForFace(side: Direction): Array[Int] = Array(slotMaterial, slotInk, slotOutput) - override def canExtractItem(slot: Int, stack: ItemStack, side: EnumFacing): Boolean = !isItemValidForSlot(slot, stack) + override def canTakeItemThroughFace(slot: Int, stack: ItemStack, side: Direction): Boolean = !canPlaceItem(slot, stack) - override def canInsertItem(slot: Int, stack: ItemStack, side: EnumFacing): Boolean = slot != slotOutput + override def canPlaceItemThroughFace(slot: Int, stack: ItemStack, side: Direction): Boolean = slot != slotOutput } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala index eff335baf4..db290aad6e 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Rack.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Rack.scala @@ -16,25 +16,34 @@ import li.cil.oc.api.network.Packet import li.cil.oc.api.network.Visibility import li.cil.oc.api.util.StateAware import li.cil.oc.common.Slot +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs import li.cil.oc.integration.opencomputers.DriverRedstoneCard import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedInventory._ import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer +import li.cil.oc.util.RotationHelper +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory.IInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagIntArray -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.IntArrayNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +class Rack(selfType: TileEntityType[_ <: Rack]) extends TileEntity(selfType) with traits.PowerAcceptor with traits.Hub with traits.PowerBalancer + with traits.ComponentInventory with traits.Rotatable with traits.BundledRedstoneAware with Analyzable with internal.Rack with traits.StateAware with INamedContainerProvider { -class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalancer with traits.ComponentInventory with traits.Rotatable with traits.BundledRedstoneAware with Analyzable with internal.Rack with traits.StateAware { var isRelayEnabled = false - val lastData = new Array[NBTTagCompound](getSizeInventory) - val hasChanged: Array[Boolean] = Array.fill(getSizeInventory)(true) + val lastData = new Array[CompoundNBT](getContainerSize) + val hasChanged: Array[Boolean] = Array.fill(getContainerSize)(true) // Map node connections for each installed mountable. Each mountable may // have up to four outgoing connections, with the first one always being @@ -43,12 +52,12 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance // The other nodes are "secondary" connections and merely transfer network // messages. // mountable -> connectable -> side - val nodeMapping: Array[Array[Option[EnumFacing]]] = Array.fill(getSizeInventory)(Array.fill[Option[EnumFacing]](4)(None)) - val snifferNodes: Array[Array[Node]] = Array.fill(getSizeInventory)(Array.fill(3)(api.Network.newNode(this, Visibility.Neighbors).create())) + val nodeMapping: Array[Array[Option[Direction]]] = Array.fill(getContainerSize)(Array.fill[Option[Direction]](4)(None)) + val snifferNodes: Array[Array[Node]] = Array.fill(getContainerSize)(Array.fill(3)(api.Network.newNode(this, Visibility.Neighbors).create())) - def connect(slot: Int, connectableIndex: Int, side: Option[EnumFacing]): Unit = { + def connect(slot: Int, connectableIndex: Int, side: Option[Direction]): Unit = { val newSide = side match { - case Some(direction) if direction != EnumFacing.SOUTH => Option(direction) + case Some(direction) if direction != Direction.SOUTH => Option(direction) case _ => None } @@ -93,8 +102,8 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance } } - private def reconnect(plugSide: EnumFacing): Unit = { - for (slot <- 0 until getSizeInventory) { + private def reconnect(plugSide: Direction): Unit = { + for (slot <- 0 until getContainerSize) { val mapping = nodeMapping(slot) mapping(0) match { case Some(side) if toGlobal(side) == plugSide => @@ -125,11 +134,11 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance } } - protected def sendPacketToMountables(sourceSide: Option[EnumFacing], packet: Packet): Unit = { + protected def sendPacketToMountables(sourceSide: Option[Direction], packet: Packet): Unit = { // When a message arrives on a bus, also send it to all secondary nodes // connected to it. Only deliver it to that very node, if it's not the // sender, to avoid loops. - for (slot <- 0 until getSizeInventory) { + for (slot <- 0 until getContainerSize) { val mapping = nodeMapping(slot) for (connectableIndex <- 0 until 3) { mapping(connectableIndex + 1) match { @@ -150,7 +159,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance // ----------------------------------------------------------------------- // // Hub - override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = { + override def tryEnqueuePacket(sourceSide: Option[Direction], packet: Packet): Boolean = { sendPacketToMountables(sourceSide, packet) if (isRelayEnabled) super.tryEnqueuePacket(sourceSide, packet) @@ -158,7 +167,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance true } - override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet): Unit = { + override protected def relayPacket(sourceSide: Option[Direction], packet: Packet): Unit = { if (isRelayEnabled) super.relayPacket(sourceSide, packet) } @@ -190,7 +199,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance } private def relayIfMessageFromConnectable(message: Message, packet: Packet): Unit = { - for (slot <- 0 until getSizeInventory) { + for (slot <- 0 until getContainerSize) { val mountable = getMountable(slot) if (mountable != null) { val mapping = nodeMapping(slot) @@ -212,8 +221,8 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance } } - private def relayToConnectablesOnSide(message: Message, packet: Packet, sourceSide: EnumFacing): Unit = { - for (slot <- 0 until getSizeInventory) { + private def relayToConnectablesOnSide(message: Message, packet: Packet, sourceSide: Direction): Unit = { + for (slot <- 0 until getContainerSize) { val mountable = getMountable(slot) if (mountable != null) { val mapping = nodeMapping(slot) @@ -236,24 +245,24 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance // ----------------------------------------------------------------------- // // SidedEnvironment - override def canConnect(side: EnumFacing): Boolean = side != facing + override def canConnect(side: Direction): Boolean = side != facing - override def sidedNode(side: EnumFacing): Node = if (side != facing) super.sidedNode(side) else null + override def sidedNode(side: Direction): Node = if (side != facing) super.sidedNode(side) else null // ----------------------------------------------------------------------- // // power.Common - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing): Boolean = side != facing + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction): Boolean = side != facing - override protected def connector(side: EnumFacing) = Option(if (side != facing) sidedNode(side).asInstanceOf[Connector] else null) + override protected def connector(side: Direction) = Option(if (side != facing) sidedNode(side).asInstanceOf[Connector] else null) override def energyThroughput: Double = Settings.get.serverRackRate // ----------------------------------------------------------------------- // // Analyzable - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { slotAt(side, hitX, hitY, hitZ) match { case Some(slot) => components(slot) match { case Some(analyzable: Analyzable) => analyzable.onAnalyze(player, side, hitX, hitY, hitZ) @@ -273,7 +282,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance case _ => null } - override def getMountableData(slot: Int): NBTTagCompound = lastData(slot) + override def getMountableData(slot: Int): CompoundNBT = lastData(slot) override def markChanged(slot: Int): Unit = { hasChanged.synchronized(hasChanged(slot) = true) @@ -314,26 +323,32 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance // ----------------------------------------------------------------------- // // IInventory - override def getSizeInventory = 4 + override def getContainerSize = 4 - override def getInventoryStackLimit = 1 + override def getMaxStackSize = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { case (_, Some(driver)) => driver.slot(stack) == Slot.RackMountable case _ => false } - override def markDirty() { - super.markDirty() + override def setChanged() { + super.setChanged() if (isServer) { setOutputEnabled(hasRedstoneCard) ServerPacketSender.sendRackInventory(this) } else { - getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) } } + // ----------------------------------------------------------------------- // + // INamedContainerProvider + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Rack(ContainerTypes.RACK, id, playerInventory, this) + // ----------------------------------------------------------------------- // // ComponentInventory @@ -370,7 +385,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance override def updateEntity() { super.updateEntity() if (isServer && isConnected) { - lazy val connectors = EnumFacing.VALUES.map(sidedNode).collect { + lazy val connectors = Direction.values.map(sidedNode).collect { case connector: Connector => connector } components.zipWithIndex.collect { @@ -379,7 +394,7 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance hasChanged(slot) = false lastData(slot) = mountable.getData ServerPacketSender.sendRackMountableData(this, slot) - getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false) + getLevel.updateNeighborsAt(getBlockPos, getBlockState.getBlock) // These are working state dependent, so recompute them. setOutputEnabled(hasRedstoneCard) } @@ -409,54 +424,54 @@ class Rack extends traits.PowerAcceptor with traits.Hub with traits.PowerBalance private final val LastDataTag = Settings.namespace + "lastData" private final val RackDataTag = Settings.namespace + "rackData" - override def readFromNBTForServer(nbt: NBTTagCompound): Unit = { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT): Unit = { + super.loadForServer(nbt) isRelayEnabled = nbt.getBoolean(IsRelayEnabledTag) - nbt.getTagList(NodeMappingTag, NBT.TAG_INT_ARRAY).map((buses: NBTTagIntArray) => - buses.getIntArray.map(id => if (id < 0 || id == EnumFacing.SOUTH.ordinal()) None else Option(EnumFacing.getFront(id)))). + nbt.getList(NodeMappingTag, NBT.TAG_INT_ARRAY).map((buses: IntArrayNBT) => + buses.getAsIntArray.map(id => if (id < 0 || id == Direction.SOUTH.ordinal()) None else Option(Direction.from3DDataValue(id)))). copyToArray(nodeMapping) // Kickstart initialization. _isOutputEnabled = hasRedstoneCard } - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT): Unit = { + super.saveForServer(nbt) - nbt.setBoolean(IsRelayEnabledTag, isRelayEnabled) + nbt.putBoolean(IsRelayEnabledTag, isRelayEnabled) nbt.setNewTagList(NodeMappingTag, nodeMapping.map(buses => toNbt(buses.map(side => side.fold(-1)(_.ordinal()))))) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound): Unit = { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT): Unit = { + super.loadForClient(nbt) - val data = nbt.getTagList(LastDataTag, NBT.TAG_COMPOUND). - toArray[NBTTagCompound] + val data = nbt.getList(LastDataTag, NBT.TAG_COMPOUND). + toTagArray[CompoundNBT] data.copyToArray(lastData) - load(nbt.getCompoundTag(RackDataTag)) + loadData(nbt.getCompound(RackDataTag)) connectComponents() } - override def writeToNBTForClient(nbt: NBTTagCompound): Unit = { - super.writeToNBTForClient(nbt) + override def saveForClient(nbt: CompoundNBT): Unit = { + super.saveForClient(nbt) - val data = lastData.map(tag => if (tag == null) new NBTTagCompound() else tag) + val data = lastData.map(tag => if (tag == null) new CompoundNBT() else tag) nbt.setNewTagList(LastDataTag, data) - nbt.setNewCompoundTag(RackDataTag, save) + nbt.setNewCompoundTag(RackDataTag, saveData) } // ----------------------------------------------------------------------- // - def slotAt(side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Option[Int] = { + def slotAt(side: Direction, hitX: Float, hitY: Float, hitZ: Float): Option[Int] = { if (side == facing) { val globalY = (hitY * 16).toInt // [0, 15] val l = 2 val h = 14 - val slot = ((15 - globalY) - l) * getSizeInventory / (h - l) - Some(math.max(0, math.min(getSizeInventory - 1, slot))) + val slot = ((15 - globalY) - l) * getContainerSize / (h - l) + Some(math.max(0, math.min(getContainerSize - 1, slot))) } else None } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Raid.scala b/src/main/scala/li/cil/oc/common/tileentity/Raid.scala index 9b21c5523a..ac94acfda1 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Raid.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Raid.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.tileentity import java.util.UUID +import java.util.function.Consumer import li.cil.oc.Settings import li.cil.oc.api @@ -8,20 +9,26 @@ import li.cil.oc.api.Driver import li.cil.oc.api.fs.Label import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network.Visibility -import li.cil.oc.common.item.data.DriveData import li.cil.oc.common.Slot +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes +import li.cil.oc.common.item.data.DriveData import li.cil.oc.common.item.data.NodeData import li.cil.oc.server.component.FileSystem import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -class Raid extends traits.Environment with traits.Inventory with traits.Rotatable with Analyzable { +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +class Raid(selfType: TileEntityType[_ <: Raid]) extends TileEntity(selfType) with traits.Environment with traits.Inventory with traits.Rotatable with Analyzable with INamedContainerProvider { val node = api.Network.newNode(this, Visibility.None).create() var filesystem: Option[FileSystem] = None @@ -32,19 +39,19 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl var lastAccess = 0L // For client side rendering. - val presence = Array.fill(getSizeInventory)(false) + val presence = Array.fill(getContainerSize)(false) // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(filesystem.map(_.node).orNull) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(filesystem.map(_.node).orNull) // ----------------------------------------------------------------------- // - override def getSizeInventory = 3 + override def getContainerSize = 3 - override def getInventoryStackLimit = 1 + override def getMaxStackSize = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack) = Option(Driver.driverFor(stack, getClass)) match { + override def canPlaceItem(slot: Int, stack: ItemStack) = Option(Driver.driverFor(stack, getClass)) match { case Some(driver) => driver.slot(stack) == Slot.HDD case _ => false } @@ -57,8 +64,8 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl } } - override def markDirty() { - super.markDirty() + override def setChanged() { + super.setChanged() // Makes the implementation of the comparator output easier. items.map(!_.isEmpty).copyToArray(presence) } @@ -70,13 +77,20 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl filesystem.foreach(fs => { fs.fileSystem.close() fs.fileSystem.list("/").foreach(fs.fileSystem.delete) - fs.save(new NBTTagCompound()) // Flush buffered fs. + fs.saveData(new CompoundNBT()) // Flush buffered fs. fs.node.remove() filesystem = None }) } } + // Uses the loot system, so nope. + override def forAllLoot(dst: Consumer[ItemStack]) = () + + override def dropSlot(slot: Int, count: Int = getMaxStackSize, direction: Option[Direction]) = false + + override def dropAllSlots() = () + def tryCreateRaid(id: String) { if (items.count(!_.isEmpty) == items.length && filesystem.fold(true)(fs => fs.node == null || fs.node.address != id)) { filesystem.foreach(fs => if (fs.node != null) fs.node.remove()) @@ -84,15 +98,15 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl val drive = new DriveData(fsStack) drive.lockInfo = "" drive.isUnmanaged = false - drive.save(fsStack) + drive.saveData(fsStack) }) val fs = api.FileSystem.asManagedEnvironment( api.FileSystem.fromSaveDirectory(id, wipeDisksAndComputeSpace, Settings.get.bufferChanges), label, this, Settings.resourceDomain + ":hdd_access", 6). asInstanceOf[FileSystem] - val nbtToSetAddress = new NBTTagCompound() - nbtToSetAddress.setString(NodeData.AddressTag, id) - fs.node.load(nbtToSetAddress) + val nbtToSetAddress = new CompoundNBT() + nbtToSetAddress.putString(NodeData.AddressTag, id) + fs.node.loadData(nbtToSetAddress) fs.node.setVisibility(Visibility.Network) // Ensure we're in a network before connecting the raid fs. api.Network.joinNewNetwork(node) @@ -106,10 +120,10 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl case Some(driver) => driver.createEnvironment(hdd, this) match { case fs: FileSystem => val nbt = driver.dataTag(hdd) - fs.load(nbt) + fs.loadData(nbt) fs.fileSystem.close() fs.fileSystem.list("/").foreach(fs.fileSystem.delete) - fs.save(nbt) + fs.saveData(nbt) fs.fileSystem.spaceTotal.toInt case _ => 0L // Ignore. } @@ -120,40 +134,45 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl // ----------------------------------------------------------------------- // + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Raid(ContainerTypes.RAID, id, playerInventory, this) + + // ----------------------------------------------------------------------- // + private final val FileSystemTag = Settings.namespace + "fs" private final val PresenceTag = Settings.namespace + "presence" private final val LabelTag = Settings.namespace + "label" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - if (nbt.hasKey(FileSystemTag)) { - val tag = nbt.getCompoundTag(FileSystemTag) - tryCreateRaid(tag.getCompoundTag(NodeData.NodeTag).getString(NodeData.AddressTag)) - filesystem.foreach(fs => fs.load(tag)) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + if (nbt.contains(FileSystemTag)) { + val tag = nbt.getCompound(FileSystemTag) + tryCreateRaid(tag.getCompound(NodeData.NodeTag).getString(NodeData.AddressTag)) + filesystem.foreach(fs => fs.loadData(tag)) } - label.load(nbt) + label.loadData(nbt) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - filesystem.foreach(fs => nbt.setNewCompoundTag(FileSystemTag, fs.save)) - label.save(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + filesystem.foreach(fs => nbt.setNewCompoundTag(FileSystemTag, fs.saveData)) + label.saveData(nbt) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) nbt.getByteArray(PresenceTag). map(_ != 0). copyToArray(presence) label.setLabel(nbt.getString(LabelTag)) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setTag(PresenceTag, items.map(!_.isEmpty)) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.put(PresenceTag, items.map(!_.isEmpty)) if (label.getLabel != null) - nbt.setString(LabelTag, label.getLabel) + nbt.putString(LabelTag, label.getLabel) } // ----------------------------------------------------------------------- // @@ -165,14 +184,14 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl override def setLabel(value: String) = label = Option(value).map(_.take(16)).orNull - override def load(nbt: NBTTagCompound) { - if (nbt.hasKey(Settings.namespace + "label")) { + override def loadData(nbt: CompoundNBT) { + if (nbt.contains(Settings.namespace + "label")) { label = nbt.getString(Settings.namespace + "label") } } - override def save(nbt: NBTTagCompound) { - nbt.setString(Settings.namespace + "label", label) + override def saveData(nbt: CompoundNBT) { + nbt.putString(Settings.namespace + "label", label) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Redstone.scala b/src/main/scala/li/cil/oc/common/tileentity/Redstone.scala index 19acb84f6f..23b657fba2 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Redstone.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Redstone.scala @@ -10,10 +10,12 @@ import li.cil.oc.integration.util.BundledRedstone import li.cil.oc.server.component import li.cil.oc.server.component.RedstoneVanilla import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction -class Redstone extends traits.Environment with traits.BundledRedstoneAware with traits.Tickable { +class Redstone(selfType: TileEntityType[_ <: Redstone]) extends TileEntity(selfType) with traits.Environment with traits.BundledRedstoneAware with traits.Tickable { val instance: RedstoneVanilla = if (BundledRedstone.isAvailable) new component.Redstone.Bundled(this) @@ -32,14 +34,14 @@ class Redstone extends traits.Environment with traits.BundledRedstoneAware with private final val RedstoneTag = Settings.namespace + "redstone" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - instance.load(nbt.getCompoundTag(RedstoneTag)) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + instance.loadData(nbt.getCompound(RedstoneTag)) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setNewCompoundTag(RedstoneTag, instance.save) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + nbt.setNewCompoundTag(RedstoneTag, instance.saveData) } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/common/tileentity/Relay.scala b/src/main/scala/li/cil/oc/common/tileentity/Relay.scala index d1410d5b04..2c67d78bdd 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Relay.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Relay.scala @@ -24,21 +24,29 @@ import li.cil.oc.api.network.WirelessEndpoint import li.cil.oc.common.InventorySlots import li.cil.oc.common.Slot import li.cil.oc.common.Tier +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.integration.Mods import li.cil.oc.integration.opencomputers.DriverLinkedCard import li.cil.oc.server.network.QuantumNetwork import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraft.util.Util import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +class Relay(selfType: TileEntityType[_ <: Relay]) extends TileEntity(selfType) with traits.Hub with traits.ComponentInventory + with traits.PowerAcceptor with Analyzable with WirelessEndpoint with QuantumNetwork.QuantumNode with INamedContainerProvider { -class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerAcceptor with Analyzable with WirelessEndpoint with QuantumNetwork.QuantumNode { lazy final val WirelessNetworkCardTier1: ItemInfo = api.Items.get(Constants.ItemName.WirelessNetworkCardTier1) lazy final val WirelessNetworkCardTier2: ItemInfo = api.Items.get(Constants.ItemName.WirelessNetworkCardTier2) lazy final val LinkedCard: ItemInfo = api.Items.get(Constants.ItemName.LinkedCard) @@ -79,10 +87,10 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override protected def hasConnector(side: EnumFacing) = true + @OnlyIn(Dist.CLIENT) + override protected def hasConnector(side: Direction) = true - override protected def connector(side: EnumFacing): Option[Connector] = sidedNode(side) match { + override protected def connector(side: Direction): Option[Connector] = sidedNode(side) match { case connector: Connector => Option(connector) case _ => None } @@ -91,10 +99,10 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { if (isWirelessEnabled) { - player.sendMessage(Localization.Analyzer.WirelessStrength(strength)) - Array(componentNodes(side.getIndex)) + player.sendMessage(Localization.Analyzer.WirelessStrength(strength), Util.NIL_UUID) + Array(componentNodes(side.get3DDataValue)) } else null } @@ -121,14 +129,20 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA // ----------------------------------------------------------------------- // - protected def queueMessage(source: String, destination: String, port: Int, answerPort: Int, args: Array[AnyRef]) { - for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) { - val address = s"cc${computer.getID}_${computer.getAttachmentName}" - if (source != address && Option(destination).forall(_ == address) && openPorts(computer).contains(port)) - computer.queueEvent("modem_message", Array(Seq(computer.getAttachmentName, Int.box(port), Int.box(answerPort)) ++ args.map { - case x: Array[Byte] => new String(x, Charsets.UTF_8) - case x => x - }: _*)) + // Isolated from parent class so automatic callbacks don't depend on optional mods. + protected object RelayCCAdapter { + def queueMessage(source: String, destination: String, port: Int, answerPort: Int, args: Array[AnyRef]) { + for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) { + val address = s"cc${computer.getID}_${computer.getAttachmentName}" + if (source != address && Option(destination).forall(_ == address) && openPorts(computer).contains(port)) { + val header = Seq(computer.getAttachmentName, Int.box(port), Int.box(answerPort)) + val payload = args.map { + case x: Array[Byte] => new String(x, Charsets.UTF_8) + case x => x + } + computer.queueEvent("modem_message", Array((header :+ (if (payload.length > 1) payload else payload(0))): _*): _*) + } + } } } @@ -148,17 +162,17 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA val computers = mutable.Buffer.empty[AnyRef] - override def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet): Boolean = { + override def tryEnqueuePacket(sourceSide: Option[Direction], packet: Packet): Boolean = { if (Mods.ComputerCraft.isModAvailable) { packet.data.headOption match { - case Some(answerPort: java.lang.Double) => queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1)) - case _ => queueMessage(packet.source, packet.destination, packet.port, -1, packet.data) + case Some(answerPort: java.lang.Double) => RelayCCAdapter.queueMessage(packet.source, packet.destination, packet.port, answerPort.toInt, packet.data.drop(1)) + case _ => RelayCCAdapter.queueMessage(packet.source, packet.destination, packet.port, -1, packet.data) } } super.tryEnqueuePacket(sourceSide, packet) } - override protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet): Unit = { + override protected def relayPacket(sourceSide: Option[Direction], packet: Packet): Unit = { super.relayPacket(sourceSide, packet) val tryChangeBuffer = sourceSide match { @@ -228,8 +242,8 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA case Some(driver) if driver.slot(stack) == Slot.CPU => relayDelay = math.max(1, relayBaseDelay - ((driver.tier(stack) + 1) * relayDelayPerUpgrade).toInt) case Some(driver) if driver.slot(stack) == Slot.Memory => - relayAmount = math.max(1, relayBaseAmount + (Delegator.subItem(stack) match { - case Some(ram: item.Memory) => (ram.tier + 1) * relayAmountPerUpgrade + relayAmount = math.max(1, relayBaseAmount + (stack.getItem match { + case ram: item.Memory => (ram.tier + 1) * relayAmountPerUpgrade case _ => (driver.tier(stack) + 1) * (relayAmountPerUpgrade * 2) })) case Some(driver) if driver.slot(stack) == Slot.HDD => @@ -240,7 +254,7 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA wirelessTier = if (descriptor == WirelessNetworkCardTier1) Tier.One else Tier.Two if (descriptor == LinkedCard) { val data = DriverLinkedCard.dataTag(stack) - if (data.hasKey(Settings.namespace + "tunnel")) { + if (data.contains(Settings.namespace + "tunnel")) { tunnel = data.getString(Settings.namespace + "tunnel") isLinkedEnabled = true QuantumNetwork.add(this) @@ -263,9 +277,9 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA } } - override def getSizeInventory: Int = InventorySlots.relay.length + override def getContainerSize: Int = InventorySlots.relay.length - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = Option(Driver.driverFor(stack, getClass)).fold(false)(driver => { val provided = InventorySlots.relay(slot) val tierSatisfied = driver.slot(stack) == provided.slot && driver.tier(stack) <= provided.tier @@ -276,38 +290,43 @@ class Relay extends traits.Hub with traits.ComponentInventory with traits.PowerA // ----------------------------------------------------------------------- // + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Relay(ContainerTypes.RELAY, id, playerInventory, this) + + // ----------------------------------------------------------------------- // + private final val StrengthTag = Settings.namespace + "strength" private final val IsRepeaterTag = Settings.namespace + "isRepeater" private final val ComponentNodesTag = Settings.namespace + "componentNodes" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) for (slot <- items.indices) if (!items(slot).isEmpty) { updateLimits(slot, items(slot)) } - if (nbt.hasKey(StrengthTag)) { + if (nbt.contains(StrengthTag)) { strength = nbt.getDouble(StrengthTag) max 0 min maxWirelessRange } - if (nbt.hasKey(IsRepeaterTag)) { + if (nbt.contains(IsRepeaterTag)) { isRepeater = nbt.getBoolean(IsRepeaterTag) } - nbt.getTagList(ComponentNodesTag, NBT.TAG_COMPOUND).toArray[NBTTagCompound]. + nbt.getList(ComponentNodesTag, NBT.TAG_COMPOUND).toTagArray[CompoundNBT]. zipWithIndex.foreach { - case (tag, index) => componentNodes(index).load(tag) + case (tag, index) => componentNodes(index).loadData(tag) } } - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - super.writeToNBTForServer(nbt) - nbt.setDouble(StrengthTag, strength) - nbt.setBoolean(IsRepeaterTag, isRepeater) + override def saveForServer(nbt: CompoundNBT): Unit = { + super.saveForServer(nbt) + nbt.putDouble(StrengthTag, strength) + nbt.putBoolean(IsRepeaterTag, isRepeater) nbt.setNewTagList(ComponentNodesTag, componentNodes.map { case node: Node => - val tag = new NBTTagCompound() - node.save(tag) + val tag = new CompoundNBT() + node.saveData(tag) tag - case _ => new NBTTagCompound() + case _ => new CompoundNBT() }) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala index 5ab733c9b4..ec7a82e547 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.tileentity import java.util.UUID +import java.util.function.Consumer import li.cil.oc._ import li.cil.oc.api.Driver @@ -14,6 +15,8 @@ import li.cil.oc.client.gui import li.cil.oc.common.EventHandler import li.cil.oc.common.Slot import li.cil.oc.common.Tier +import li.cil.oc.common.container +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.inventory.InventoryProxy import li.cil.oc.common.inventory.InventorySelection import li.cil.oc.common.inventory.TankSelection @@ -32,27 +35,33 @@ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ import net.minecraft.block.Block -import net.minecraft.block.BlockLiquid +import net.minecraft.block.Blocks +import net.minecraft.block.FlowingFluidBlock import net.minecraft.client.Minecraft -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.init.Blocks -import net.minecraft.init.SoundEvents -import net.minecraft.inventory.EntityEquipmentSlot +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.fluid.Fluid +import net.minecraft.inventory.EquipmentSlotType +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.util.Direction import net.minecraft.util.SoundCategory -import net.minecraft.util.math.AxisAlignedBB +import net.minecraft.util.SoundEvents +import net.minecraft.util.Util import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.StringTextComponent import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.capabilities.Capability +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier import net.minecraftforge.fluids._ import net.minecraftforge.fluids.capability.CapabilityFluidHandler -import net.minecraftforge.fluids.capability.FluidTankProperties import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.fluids.capability.IFluidTankProperties -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import scala.collection.mutable @@ -62,23 +71,28 @@ import scala.collection.mutable // robot moves we only create a new proxy tile entity, hook the instance of this // class that was held by the old proxy to it and can then safely forget the // old proxy, which will be cleaned up by Minecraft like any other tile entity. -class Robot extends traits.Computer with traits.PowerInformation with traits.RotatableTile with IFluidHandler with internal.Robot with InventorySelection with TankSelection { +class Robot extends TileEntity(TileEntityTypes.ROBOT) with traits.Computer with traits.PowerInformation with traits.RotatableTile + with IFluidHandler with internal.Robot with InventorySelection with TankSelection with INamedContainerProvider { + var proxy: RobotProxy = _ val info = new RobotData() val bot: component.Robot = if (isServer) new component.Robot(this) else null + val fluidCap: LazyOptional[IFluidHandler] = LazyOptional.of(new NonNullSupplier[IFluidHandler] { + override def get = Robot.this + }) + if (isServer) { machine.setCostPerTick(Settings.get.robotCost) } - // ----------------------------------------------------------------------- // - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) - capability.cast(this.asInstanceOf[T]) + fluidCap.cast() else super.getCapability(capability, facing) } @@ -90,29 +104,29 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot val equipmentInventory = new InventoryProxy { override def inventory: Robot = Robot.this - override def getSizeInventory = 4 + override def getContainerSize = 4 } // Wrapper for the part of the inventory that is mutable. val mainInventory = new InventoryProxy { override def inventory: Robot = Robot.this - override def getSizeInventory: Int = Robot.this.inventorySize + override def getContainerSize: Int = Robot.this.inventorySize - override def offset: Int = equipmentInventory.getSizeInventory + override def offset: Int = equipmentInventory.getContainerSize } val actualInventorySize = 100 - def maxInventorySize: Int = actualInventorySize - equipmentInventory.getSizeInventory - componentCount + def maxInventorySize: Int = actualInventorySize - equipmentInventory.getContainerSize - componentCount var inventorySize: Int = -1 var selectedSlot = 0 override def setSelectedSlot(index: Int): Unit = { - selectedSlot = index max 0 min mainInventory.getSizeInventory - 1 - if (getWorld != null) { + selectedSlot = index max 0 min mainInventory.getContainerSize - 1 + if (getLevel != null) { ServerPacketSender.sendRobotSelectedSlotChange(this) } } @@ -136,12 +150,12 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot override def player: Player = { agent.Player.updatePositionAndRotation(player_, facing, facing) - agent.Player.setInventoryPlayerItems(player_) + agent.Player.setPlayerInventoryItems(player_) player_ } - override def synchronizeSlot(slot: Int): Unit = if (slot >= 0 && slot < getSizeInventory) this.synchronized { - val stack = getStackInSlot(slot) + override def synchronizeSlot(slot: Int): Unit = if (slot >= 0 && slot < getContainerSize) this.synchronized { + val stack = getItem(slot) components(slot) match { case Some(component) => // We're guaranteed to have a driver for entries. @@ -153,9 +167,9 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot def containerSlots: Range.Inclusive = 1 to info.containers.length - def componentSlots: Range = getSizeInventory - componentCount until getSizeInventory + def componentSlots: Range = getContainerSize - componentCount until getContainerSize - def inventorySlots: Range = equipmentInventory.getSizeInventory until (equipmentInventory.getSizeInventory + mainInventory.getSizeInventory) + def inventorySlots: Range = equipmentInventory.getContainerSize until (equipmentInventory.getContainerSize + mainInventory.getContainerSize) def setLightColor(value: Int): Unit = { info.lightColor = value @@ -196,17 +210,17 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot override def setName(name: String): Unit = info.name = name - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { - player.sendMessage(Localization.Analyzer.RobotOwner(ownerName)) - player.sendMessage(Localization.Analyzer.RobotName(player_.getName)) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = { + player.sendMessage(Localization.Analyzer.RobotOwner(ownerName), Util.NIL_UUID) + player.sendMessage(Localization.Analyzer.RobotName(player_.getName.getString), Util.NIL_UUID) MinecraftForge.EVENT_BUS.post(new RobotAnalyzeEvent(this, player)) super.onAnalyze(player, side, hitX, hitY, hitZ) } - def move(direction: EnumFacing): Boolean = { - val oldPosition = getPos - val newPosition = oldPosition.offset(direction) - if (!getWorld.isBlockLoaded(newPosition)) { + def move(direction: Direction): Boolean = { + val oldPosition = getBlockPos + val newPosition = oldPosition.relative(direction) + if (!getLevel.isLoaded(newPosition)) { return false // Don't fall off the earth. } @@ -218,10 +232,9 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot val blockRobotProxy = api.Items.get(Constants.BlockName.Robot).block.asInstanceOf[common.block.RobotProxy] val blockRobotAfterImage = api.Items.get(Constants.BlockName.RobotAfterimage).block.asInstanceOf[common.block.RobotAfterimage] - val wasAir = getWorld.isAirBlock(newPosition) - val state = getWorld.getBlockState(newPosition) + val wasAir = getLevel.isEmptyBlock(newPosition) + val state = getLevel.getBlockState(newPosition) val block = state.getBlock - val metadata = block.getMetaFromState(state) try { // Setting this will make the tile entity created via the following call // to setBlock to re-use our "real" instance as the inner object, instead @@ -231,16 +244,16 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot // worked before the client is notified so that we can use the same trick on // the client by sending a corresponding packet. This also saves us from // having to send the complete state again (e.g. screen buffer) each move. - getWorld.setBlockToAir(newPosition) + getLevel.setBlockAndUpdate(newPosition, Blocks.AIR.defaultBlockState) // In some cases (though I couldn't quite figure out which one) setBlock // will return true, even though the block was not created / adjusted. - val created = getWorld.setBlockState(newPosition, getWorld.getBlockState(oldPosition), 1) && - getWorld.getTileEntity(newPosition) == proxy + val created = getLevel.setBlock(newPosition, getLevel.getBlockState(oldPosition), 1) && + getLevel.getBlockEntity(newPosition) == proxy if (created) { - assert(getPos == newPosition) - getWorld.setBlockState(oldPosition, net.minecraft.init.Blocks.AIR.getDefaultState, 1) - getWorld.setBlockState(oldPosition, blockRobotAfterImage.getDefaultState, 1) - assert(getWorld.getBlockState(oldPosition).getBlock == blockRobotAfterImage) + assert(getBlockPos == newPosition) + getLevel.setBlock(oldPosition, Blocks.AIR.defaultBlockState, 1) + getLevel.setBlock(oldPosition, blockRobotAfterImage.defaultBlockState, 1) + assert(getLevel.getBlockState(oldPosition).getBlock == blockRobotAfterImage) // Here instead of Lua callback so that it gets called on client, too. val moveTicks = math.max((Settings.get.moveDelay * 20).toInt, 1) setAnimateMove(oldPosition, moveTicks) @@ -253,29 +266,24 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot // If we broke some replaceable block (like grass) play its break sound. if (!wasAir) { if (block != Blocks.AIR && block != blockRobotAfterImage) { - if (FluidRegistry.lookupFluidForBlock(block) == null && - !block.isInstanceOf[BlockFluidBase] && - !block.isInstanceOf[BlockLiquid]) { - getWorld.playEvent(2001, newPosition, Block.getIdFromBlock(block) + (metadata << 12)) + if (!state.getFluidState.isEmpty) { + getLevel.playLocalSound(newPosition.getX + 0.5, newPosition.getY + 0.5, newPosition.getZ + 0.5, SoundEvents.WATER_AMBIENT, SoundCategory.BLOCKS, + getLevel.random.nextFloat * 0.25f + 0.75f, getLevel.random.nextFloat * 1.0f + 0.5f, false) } - else { - val sx = newPosition.getX + 0.5 - val sy = newPosition.getY + 0.5 - val sz = newPosition.getZ + 0.5 - getWorld.playSound(sx, sy, sz, SoundEvents.BLOCK_WATER_AMBIENT, SoundCategory.BLOCKS, - getWorld.rand.nextFloat * 0.25f + 0.75f, getWorld.rand.nextFloat * 1.0f + 0.5f, false) + if (!block.isInstanceOf[FlowingFluidBlock]) { + getLevel.levelEvent(2001, newPosition, Block.getId(state)) } } } - getWorld.notifyBlockUpdate(oldPosition) - getWorld.notifyBlockUpdate(newPosition) + getLevel.notifyBlockUpdate(oldPosition) + getLevel.notifyBlockUpdate(newPosition) } - assert(!isInvalid) + assert(!isRemoved) } else { - getWorld.setBlockToAir(newPosition) + getLevel.setBlockAndUpdate(newPosition, Blocks.AIR.defaultBlockState) } - created && this.pos == newPosition + created && getBlockPos == newPosition } finally { blockRobotProxy.moving.set(None) @@ -327,16 +335,6 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot // ----------------------------------------------------------------------- // - override def shouldRenderInPass(pass: Int) = true - - override def getRenderBoundingBox: AxisAlignedBB = - if (getBlockType != null && getWorld != null) - getBlockType.getCollisionBoundingBox(getWorld.getBlockState(getPos), getWorld, getPos).grow(0.5, 0.5, 0.5).offset(getPos) - else - new AxisAlignedBB(0, 0, 0, 1, 1, 1).offset(getPos) - - // ----------------------------------------------------------------------- // - override def updateEntity() { if (animationTicksLeft > 0) { animationTicksLeft -= 1 @@ -348,7 +346,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot } super.updateEntity() if (isServer) { - if (getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (getLevel.getGameTime % Settings.get.tickFrequency == 0) { if (info.tier == 3) { bot.node.changeBuffer(Double.PositiveInfinity) } @@ -360,8 +358,8 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot } if (!appliedToolEnchantments) { appliedToolEnchantments = true - StackOption(getStackInSlot(0)) match { - case SomeStack(item) => player_.getAttributeMap.applyAttributeModifiers(item.getAttributeModifiers(EntityEquipmentSlot.MAINHAND)) + StackOption(getItem(0)) match { + case SomeStack(item) => player_.getAttributes.addTransientAttributeModifiers(item.getAttributeModifiers(EquipmentSlotType.MAINHAND)) case _ => } } @@ -370,9 +368,9 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot client.Sound.updatePosition(this) } - for (slot <- 0 until equipmentInventory.getSizeInventory + mainInventory.getSizeInventory) { - getStackInSlot(slot) match { - case stack: ItemStack => try stack.updateAnimation(getWorld, if (!getWorld.isRemote) player_ else null, slot, slot == 0) catch { + for (slot <- 0 until equipmentInventory.getContainerSize + mainInventory.getContainerSize) { + getItem(slot) match { + case stack: ItemStack => try stack.inventoryTick(getLevel, if (!getLevel.isClientSide) player_ else null, slot, slot == 0) catch { case ignored: NullPointerException => // Client side item updates that need a player instance... } case _ => @@ -401,9 +399,9 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot override def dispose() { super.dispose() if (isClient) { - Minecraft.getMinecraft.currentScreen match { - case robotGui: gui.Robot if robotGui.robot == this => - Minecraft.getMinecraft.displayGuiScreen(null) + Minecraft.getInstance.screen match { + case robotGui: gui.Robot if robotGui.inventoryContainer.otherInventory == this => + robotGui.onClose() case _ => } } @@ -425,28 +423,28 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot private final val SwingingToolTag = Settings.namespace + "swingingTool" private final val TurnAxisTag = Settings.namespace + "turnAxis" - override def readFromNBTForServer(nbt: NBTTagCompound) { + override def loadForServer(nbt: CompoundNBT) { updateInventorySize() machine.onHostChanged() - bot.load(nbt.getCompoundTag(RobotTag)) - if (nbt.hasKey(OwnerTag)) { + bot.loadData(nbt.getCompound(RobotTag)) + if (nbt.contains(OwnerTag)) { ownerName = nbt.getString(OwnerTag) } - if (nbt.hasKey(OwnerUUIDTag)) { + if (nbt.contains(OwnerUUIDTag)) { ownerUUID = UUID.fromString(nbt.getString(OwnerUUIDTag)) } if (inventorySize > 0) { - selectedSlot = nbt.getInteger(SelectedSlotTag) max 0 min mainInventory.getSizeInventory - 1 + selectedSlot = nbt.getInt(SelectedSlotTag) max 0 min mainInventory.getContainerSize - 1 } - selectedTank = nbt.getInteger(SelectedTankTag) - animationTicksTotal = nbt.getInteger(AnimationTicksTotalTag) - animationTicksLeft = nbt.getInteger(AnimationTicksLeftTag) + selectedTank = nbt.getInt(SelectedTankTag) + animationTicksTotal = nbt.getInt(AnimationTicksTotalTag) + animationTicksLeft = nbt.getInt(AnimationTicksLeftTag) if (animationTicksLeft > 0) { - if (nbt.hasKey(MoveFromXTag)) { - val moveFromX = nbt.getInteger(MoveFromXTag) - val moveFromY = nbt.getInteger(MoveFromYTag) - val moveFromZ = nbt.getInteger(MoveFromZTag) + if (nbt.contains(MoveFromXTag)) { + val moveFromX = nbt.getInt(MoveFromXTag) + val moveFromY = nbt.getInt(MoveFromYTag) + val moveFromZ = nbt.getInt(MoveFromZTag) moveFrom = Some(new BlockPos(moveFromX, moveFromY, moveFromZ)) } swingingTool = nbt.getBoolean(SwingingToolTag) @@ -460,47 +458,47 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot } // Side check for Waila (and other mods that may call this client side). - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = if (isServer) this.synchronized { - info.save(nbt) + override def saveForServer(nbt: CompoundNBT): Unit = if (isServer) this.synchronized { + info.saveData(nbt) - // Note: computer is saved when proxy is saved (in proxy's super writeToNBT) + // Note: computer is saved when proxy is saved (in proxy's super save) // which is a bit ugly, and may be refactored some day, but it works. - nbt.setNewCompoundTag(RobotTag, bot.save) - nbt.setString(OwnerTag, ownerName) - nbt.setString(OwnerUUIDTag, ownerUUID.toString) - nbt.setInteger(SelectedSlotTag, selectedSlot) - nbt.setInteger(SelectedTankTag, selectedTank) + nbt.setNewCompoundTag(RobotTag, bot.saveData) + nbt.putString(OwnerTag, ownerName) + nbt.putString(OwnerUUIDTag, ownerUUID.toString) + nbt.putInt(SelectedSlotTag, selectedSlot) + nbt.putInt(SelectedTankTag, selectedTank) if (isAnimatingMove || isAnimatingSwing || isAnimatingTurn) { - nbt.setInteger(AnimationTicksTotalTag, animationTicksTotal) - nbt.setInteger(AnimationTicksLeftTag, animationTicksLeft) + nbt.putInt(AnimationTicksTotalTag, animationTicksTotal) + nbt.putInt(AnimationTicksLeftTag, animationTicksLeft) moveFrom match { case Some(blockPos) => - nbt.setInteger(MoveFromXTag, blockPos.getX) - nbt.setInteger(MoveFromYTag, blockPos.getY) - nbt.setInteger(MoveFromZTag, blockPos.getZ) + nbt.putInt(MoveFromXTag, blockPos.getX) + nbt.putInt(MoveFromYTag, blockPos.getY) + nbt.putInt(MoveFromZTag, blockPos.getZ) case _ => } - nbt.setBoolean(SwingingToolTag, swingingTool) - nbt.setByte(TurnAxisTag, turnAxis.toByte) + nbt.putBoolean(SwingingToolTag, swingingTool) + nbt.putByte(TurnAxisTag, turnAxis.toByte) } } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) - load(nbt) - info.load(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) + loadData(nbt) + info.loadData(nbt) updateInventorySize() - selectedSlot = nbt.getInteger(SelectedSlotTag) - animationTicksTotal = nbt.getInteger(AnimationTicksTotalTag) - animationTicksLeft = nbt.getInteger(AnimationTicksLeftTag) + selectedSlot = nbt.getInt(SelectedSlotTag) + animationTicksTotal = nbt.getInt(AnimationTicksTotalTag) + animationTicksLeft = nbt.getInt(AnimationTicksLeftTag) if (animationTicksLeft > 0) { - if (nbt.hasKey(MoveFromXTag)) { - val moveFromX = nbt.getInteger(MoveFromXTag) - val moveFromY = nbt.getInteger(MoveFromYTag) - val moveFromZ = nbt.getInteger(MoveFromZTag) + if (nbt.contains(MoveFromXTag)) { + val moveFromX = nbt.getInt(MoveFromXTag) + val moveFromY = nbt.getInt(MoveFromYTag) + val moveFromZ = nbt.getInt(MoveFromZTag) moveFrom = Some(new BlockPos(moveFromX, moveFromY, moveFromZ)) } swingingTool = nbt.getBoolean(SwingingToolTag) @@ -509,24 +507,24 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot connectComponents() } - override def writeToNBTForClient(nbt: NBTTagCompound): Unit = this.synchronized { - super.writeToNBTForClient(nbt) - save(nbt) - info.save(nbt) + override def saveForClient(nbt: CompoundNBT): Unit = this.synchronized { + super.saveForClient(nbt) + saveData(nbt) + info.saveData(nbt) - nbt.setInteger(SelectedSlotTag, selectedSlot) + nbt.putInt(SelectedSlotTag, selectedSlot) if (isAnimatingMove || isAnimatingSwing || isAnimatingTurn) { - nbt.setInteger(AnimationTicksTotalTag, animationTicksTotal) - nbt.setInteger(AnimationTicksLeftTag, animationTicksLeft) + nbt.putInt(AnimationTicksTotalTag, animationTicksTotal) + nbt.putInt(AnimationTicksLeftTag, animationTicksLeft) moveFrom match { case Some(blockPos) => - nbt.setInteger(MoveFromXTag, blockPos.getX) - nbt.setInteger(MoveFromYTag, blockPos.getY) - nbt.setInteger(MoveFromZTag, blockPos.getZ) + nbt.putInt(MoveFromXTag, blockPos.getX) + nbt.putInt(MoveFromYTag, blockPos.getY) + nbt.putInt(MoveFromZTag, blockPos.getZ) case _ => } - nbt.setBoolean(SwingingToolTag, swingingTool) - nbt.setByte(TurnAxisTag, turnAxis.toByte) + nbt.putBoolean(SwingingToolTag, swingingTool) + nbt.putByte(TurnAxisTag, turnAxis.toByte) } } @@ -556,7 +554,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot override protected def onItemAdded(slot: Int, stack: ItemStack) { if (isServer) { if (isToolSlot(slot)) { - player_.getAttributeMap.applyAttributeModifiers(stack.getAttributeModifiers(EntityEquipmentSlot.MAINHAND)) + player_.getAttributes.addTransientAttributeModifiers(stack.getAttributeModifiers(EquipmentSlotType.MAINHAND)) ServerPacketSender.sendRobotInventory(this, slot, stack) } if (isUpgradeSlot(slot)) { @@ -567,10 +565,10 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot } if (isComponentSlot(slot, stack)) { super.onItemAdded(slot, stack) - getWorld.notifyBlocksOfNeighborChange(position, getBlockType, updateObservers = false) + getLevel.notifyBlocksOfNeighborChange(position, getBlockState.getBlock, updateObservers = false) } if (isInventorySlot(slot)) { - machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getSizeInventory + 1)) + machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getContainerSize + 1)) } } else super.onItemAdded(slot, stack) @@ -580,7 +578,7 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot super.onItemRemoved(slot, stack) if (isServer) { if (isToolSlot(slot)) { - player_.getAttributeMap.removeAttributeModifiers(stack.getAttributeModifiers(EntityEquipmentSlot.MAINHAND)) + player_.getAttributes.removeAttributeModifiers(stack.getAttributeModifiers(EquipmentSlotType.MAINHAND)) ServerPacketSender.sendRobotInventory(this, slot, ItemStack.EMPTY) } if (isUpgradeSlot(slot)) { @@ -590,16 +588,16 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot common.Sound.playDiskEject(this) } if (isInventorySlot(slot)) { - machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getSizeInventory + 1)) + machine.signal("inventory_changed", Int.box(slot - equipmentInventory.getContainerSize + 1)) } if (isComponentSlot(slot, stack)) { - getWorld.notifyBlocksOfNeighborChange(position, getBlockType, updateObservers = false) + getLevel.notifyBlocksOfNeighborChange(position, getBlockState.getBlock, updateObservers = false) } } } - override def markDirty() { - super.markDirty() + override def setChanged() { + super.setChanged() // Avoid getting into a bad state on the client when updating before we // got the descriptor packet from the server. If we manage to open the // GUI before the descriptor packet arrived, close it again because it is @@ -608,9 +606,9 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot updateInventorySize() } else if (isClient) { - Minecraft.getMinecraft.currentScreen match { - case robotGui: gui.Robot if robotGui.robot == this => - Minecraft.getMinecraft.displayGuiScreen(null) + Minecraft.getInstance.screen match { + case robotGui: gui.Robot if robotGui.inventoryContainer.otherInventory == this => + robotGui.onClose() case _ => } } @@ -665,8 +663,8 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot def isInventorySlot(slot: Int): Boolean = inventorySlots contains slot - def isFloppySlot(slot: Int): Boolean = !getStackInSlot(slot).isEmpty && isComponentSlot(slot, getStackInSlot(slot)) && { - val stack = getStackInSlot(slot) + def isFloppySlot(slot: Int): Boolean = !getItem(slot).isEmpty && isComponentSlot(slot, getItem(slot)) && { + val stack = getItem(slot) Option(Driver.driverFor(stack, getClass)) match { case Some(driver) => driver.slot(stack) == Slot.Floppy case _ => false @@ -679,9 +677,9 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot override def componentSlot(address: String): Int = components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) - override def hasRedstoneCard: Boolean = (containerSlots ++ componentSlots).exists(slot => StackOption(getStackInSlot(slot)).fold(false)(DriverRedstoneCard.worksWith(_, getClass))) + override def hasRedstoneCard: Boolean = (containerSlots ++ componentSlots).exists(slot => StackOption(getItem(slot)).fold(false)(DriverRedstoneCard.worksWith(_, getClass))) - private def computeInventorySize() = math.min(maxInventorySize, (containerSlots ++ componentSlots).foldLeft(0)((acc, slot) => acc + (StackOption(getStackInSlot(slot)) match { + private def computeInventorySize() = math.min(maxInventorySize, (containerSlots ++ componentSlots).foldLeft(0)((acc, slot) => acc + (StackOption(getItem(slot)) match { case SomeStack(stack) => Option(Driver.driverFor(stack, getClass)) match { case Some(driver: item.Inventory) => driver.inventoryCapacity(stack) case _ => 0 @@ -696,23 +694,23 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot val newInventorySize = computeInventorySize() if (newInventorySize != inventorySize) { inventorySize = newInventorySize - val realSize = equipmentInventory.getSizeInventory + mainInventory.getSizeInventory + val realSize = equipmentInventory.getContainerSize + mainInventory.getContainerSize val oldSelected = selectedSlot val removed = mutable.ArrayBuffer.empty[ItemStack] - for (slot <- realSize until getSizeInventory - componentCount) { - val stack = getStackInSlot(slot) - setInventorySlotContents(slot, ItemStack.EMPTY) + for (slot <- realSize until getContainerSize - componentCount) { + val stack = getItem(slot) + setItem(slot, ItemStack.EMPTY) if (!stack.isEmpty) removed += stack } - val copyComponentCount = math.min(getSizeInventory, componentCount) - Array.copy(components, getSizeInventory - copyComponentCount, components, realSize, copyComponentCount) - for (slot <- math.max(0, getSizeInventory - componentCount) until getSizeInventory if slot < realSize || slot >= realSize + componentCount) { + val copyComponentCount = math.min(getContainerSize, componentCount) + Array.copy(components, getContainerSize - copyComponentCount, components, realSize, copyComponentCount) + for (slot <- math.max(0, getContainerSize - componentCount) until getContainerSize if slot < realSize || slot >= realSize + componentCount) { components(slot) = None } - getSizeInventory = realSize + componentCount - if (getWorld != null && isServer) { + getContainerSize = realSize + componentCount + if (getLevel != null && isServer) { for (stack <- removed) { - player().inventory.addItemStackToInventory(stack) + player().inventory.add(stack) spawnStackInWorld(stack, Option(facing)) } setSelectedSlot(oldSelected) @@ -725,36 +723,36 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot // ----------------------------------------------------------------------- // - var getSizeInventory: Int = actualInventorySize + var getContainerSize: Int = actualInventorySize - override def getInventoryStackLimit = 64 + override def getMaxStackSize = 64 - override def getStackInSlot(slot: Int): ItemStack = { - if (slot >= getSizeInventory) null // Required to always show 16 inventory slots in GUI. - else if (slot >= getSizeInventory - componentCount) { - info.components(slot - (getSizeInventory - componentCount)) + override def getItem(slot: Int): ItemStack = { + if (slot >= getContainerSize) null // Required to always show 16 inventory slots in GUI. + else if (slot >= getContainerSize - componentCount) { + info.components(slot - (getContainerSize - componentCount)) } - else super.getStackInSlot(slot) + else super.getItem(slot) } - override def setInventorySlotContents(slot: Int, stack: ItemStack) { - if (slot < getSizeInventory - componentCount && (isItemValidForSlot(slot, stack) || stack.isEmpty)) { + override def setItem(slot: Int, stack: ItemStack) { + if (slot < getContainerSize - componentCount && (canPlaceItem(slot, stack) || stack.isEmpty)) { if (!stack.isEmpty && stack.getCount > 1 && isComponentSlot(slot, stack)) { - super.setInventorySlotContents(slot, stack.splitStack(1)) + super.setItem(slot, stack.split(1)) if (stack.getCount > 0 && isServer) { - player().inventory.addItemStackToInventory(stack) + player().inventory.add(stack) spawnStackInWorld(stack, Option(facing)) } } - else super.setInventorySlotContents(slot, stack) + else super.setItem(slot, stack) } - else if (!stack.isEmpty && stack.getCount > 0 && !getWorld.isRemote) spawnStackInWorld(stack, Option(EnumFacing.UP)) + else if (!stack.isEmpty && stack.getCount > 0 && !getLevel.isClientSide) spawnStackInWorld(stack, Option(Direction.UP)) } - override def isUsableByPlayer(player: EntityPlayer): Boolean = - super.isUsableByPlayer(player) && (!isCreative || player.capabilities.isCreativeMode) + override def stillValid(player: PlayerEntity): Boolean = + super.stillValid(player) && (!isCreative || player.isCreative) - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack, getClass))) match { case (0, _) => true // Allow anything in the tool slot. case (i, Some(driver)) if isContainerSlot(i) => // Yay special cases! Dynamic screens kind of work, but are pretty derpy @@ -774,30 +772,51 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot // ----------------------------------------------------------------------- // - override def dropSlot(slot: Int, count: Int, direction: Option[EnumFacing]): Boolean = - InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), mainInventory, slot, count, direction) + override def getDisplayName = StringTextComponent.EMPTY + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new container.Robot(ContainerTypes.ROBOT, id, playerInventory, this, new container.RobotInfo(this)) + + // ----------------------------------------------------------------------- // + + override def forAllLoot(dst: Consumer[ItemStack]) { + Option(getItem(0)) match { + case Some(stack) if stack.getCount > 0 => dst.accept(stack) + case _ => + } + for (slot <- containerSlots) { + Option(getItem(slot)) match { + case Some(stack) if stack.getCount > 0 => dst.accept(stack) + case _ => + } + } + InventoryUtils.forAllSlots(mainInventory, dst) + } + + override def dropSlot(slot: Int, count: Int, direction: Option[Direction]): Boolean = + InventoryUtils.dropSlot(BlockPosition(x, y, z, getLevel), mainInventory, slot, count, direction) override def dropAllSlots(): Unit = { - InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), this, 0, Int.MaxValue) + InventoryUtils.dropSlot(BlockPosition(x, y, z, getLevel), this, 0, Int.MaxValue) for (slot <- containerSlots) { - InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), this, slot, Int.MaxValue) + InventoryUtils.dropSlot(BlockPosition(x, y, z, getLevel), this, slot, Int.MaxValue) } - InventoryUtils.dropAllSlots(BlockPosition(x, y, z, getWorld), mainInventory) + InventoryUtils.dropAllSlots(BlockPosition(x, y, z, getLevel), mainInventory) } // ----------------------------------------------------------------------- // - override def canExtractItem(slot: Int, stack: ItemStack, side: EnumFacing): Boolean = - getSlotsForFace(side).contains(slot) + override def canTakeItemThroughFace(slot: Int, stack: ItemStack, side: Direction): Boolean = + getSlotsForFace(side).toSeq.contains(slot) - override def canInsertItem(slot: Int, stack: ItemStack, side: EnumFacing): Boolean = - getSlotsForFace(side).contains(slot) && - isItemValidForSlot(slot, stack) + override def canPlaceItemThroughFace(slot: Int, stack: ItemStack, side: Direction): Boolean = + getSlotsForFace(side).toSeq.contains(slot) && + canPlaceItem(slot, stack) - override def getSlotsForFace(side: EnumFacing): Array[Int] = + override def getSlotsForFace(side: Direction): Array[Int] = toLocal(side) match { - case EnumFacing.WEST => Array(0) // Tool - case EnumFacing.EAST => containerSlots.toArray + case Direction.WEST => Array(0) // Tool + case Direction.EAST => containerSlots.toArray case _ => inventorySlots.toArray } @@ -820,43 +839,43 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot // ----------------------------------------------------------------------- // - override def fill(resource: FluidStack, doFill: Boolean): Int = + override def getTanks = tankCount + + override def getFluidInTank(tank: Int): FluidStack = tryGetTank(selectedTank) match { case Some(t) => - t.fill(resource, doFill) - case _ => 0 + t.getFluid + case _ => FluidStack.EMPTY } - override def drain(resource: FluidStack, doDrain: Boolean): FluidStack = + override def getTankCapacity(tank: Int): Int = tryGetTank(selectedTank) match { - case Some(t) if t.getFluid != null && t.getFluid.isFluidEqual(resource) => - t.drain(resource.amount, doDrain) - case _ => null + case Some(t) => + t.getCapacity + case _ => 0 } - override def drain(maxDrain: Int, doDrain: Boolean): FluidStack = { + override def isFluidValid(tank: Int, resource: FluidStack) = true + + override def fill(resource: FluidStack, action: FluidAction): Int = tryGetTank(selectedTank) match { case Some(t) => - t.drain(maxDrain, doDrain) - case _ => null + t.fill(resource, action) + case _ => 0 } - } - def canFill(fluid: Fluid): Boolean = { + override def drain(resource: FluidStack, action: FluidAction): FluidStack = tryGetTank(selectedTank) match { - case Some(t) => t.getFluid == null || t.getFluid.getFluid == fluid - case _ => false + case Some(t) if t.getFluid != null && t.getFluid.isFluidEqual(resource) => + t.drain(resource.getAmount, action) + case _ => FluidStack.EMPTY } - } - def canDrain(fluid: Fluid): Boolean = { + override def drain(maxDrain: Int, action: FluidAction): FluidStack = { tryGetTank(selectedTank) match { - case Some(t) => t.getFluid != null && t.getFluid.getFluid == fluid - case _ => false + case Some(t) => + t.drain(maxDrain, action) + case _ => FluidStack.EMPTY } } - - override def getTankProperties: Array[IFluidTankProperties] = FluidTankProperties.convert(components.collect { - case Some(t: IFluidTank) => t.getInfo - }).map(_.asInstanceOf[IFluidTankProperties]) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/RobotProxy.scala b/src/main/scala/li/cil/oc/common/tileentity/RobotProxy.scala index 3b41bd9c3b..1e5266f4da 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/RobotProxy.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/RobotProxy.scala @@ -1,6 +1,7 @@ package li.cil.oc.common.tileentity import java.util.UUID +import java.util.function.Consumer import li.cil.oc.api import li.cil.oc.api.internal @@ -15,30 +16,46 @@ import li.cil.oc.common.tileentity.traits.RedstoneAware import li.cil.oc.server.agent.Player import li.cil.oc.server.{PacketSender => ServerPacketSender} import net.minecraftforge.common.capabilities.Capability +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier import net.minecraftforge.fluids.capability.CapabilityFluidHandler import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import net.minecraft.entity.Entity -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.fluid.Fluid import net.minecraft.inventory.ISidedInventory import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraft.util.math.AxisAlignedBB -import net.minecraftforge.fluids.Fluid +import net.minecraft.util.text.ITextComponent import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.IFluidTank -import net.minecraftforge.fluids.capability.IFluidTankProperties -class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInformation with traits.RotatableTile with ISidedInventory with IFluidHandler with internal.Robot { - def this() = this(new Robot()) +class RobotProxy(selfType: TileEntityType[_ <: RobotProxy], val robot: Robot) extends TileEntity(selfType) + with traits.Computer with traits.PowerInformation with traits.RotatableTile with ISidedInventory with IFluidHandler with internal.Robot { + + def this(selfType: TileEntityType[_ <: RobotProxy]) = this(selfType, new Robot()) // ----------------------------------------------------------------------- // - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { + private val wrapper = LazyOptional.of(new NonNullSupplier[IFluidHandler] { + override def get = RobotProxy.this + }) + + override def invalidateCaps() { + super.invalidateCaps() + wrapper.invalidate() + } + + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) - capability.cast(this.asInstanceOf[T]) + wrapper.cast[T] else super.getCapability(capability, facing) } @@ -53,7 +70,7 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo override def equipmentInventory: InventoryProxy { def inventory: Robot - def getSizeInventory: Int + def getContainerSize: Int } = robot.equipmentInventory override def mainInventory: InventoryProxy { @@ -61,7 +78,7 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo def inventory: Robot - def getSizeInventory: Int + def getContainerSize: Int } = robot.mainInventory override def tank: MultiTank { @@ -126,7 +143,7 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo def setName(context: Context, args: Arguments): Array[AnyRef] = { val oldName = robot.name val newName: String = args.checkString(0) - if (machine.isRunning) return result(Unit, "is running") + if (machine.isRunning) return result((), "is running") setName(newName) ServerPacketSender.sendRobotNameChange(robot) result(oldName) @@ -149,20 +166,19 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo robot.updateEntity() } - override def validate() { - super.validate() + override def clearRemoved() { + super.clearRemoved() val firstProxy = robot.proxy == null robot.proxy = this - robot.setWorld(getWorld) - robot.setPos(getPos) + robot.setLevelAndPosition(getLevel, getBlockPos) if (firstProxy) { - robot.validate() + robot.clearRemoved() } if (isServer) { // Use the same address we use internally on the outside. - val nbt = new NBTTagCompound() - nbt.setString("address", robot.node.address) - node.load(nbt) + val nbt = new CompoundNBT() + nbt.putString("address", robot.node.address) + node.loadData(nbt) } } @@ -173,37 +189,36 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo } } - override def readFromNBTForServer(nbt: NBTTagCompound) { - robot.info.load(nbt) - super.readFromNBTForServer(nbt) - robot.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + robot.info.loadData(nbt) + super.loadForServer(nbt) + robot.loadForServer(nbt) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - robot.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + robot.saveForServer(nbt) } - override def save(nbt: NBTTagCompound): Unit = robot.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = robot.saveData(nbt) - override def load(nbt: NBTTagCompound): Unit = robot.load(nbt) + override def loadData(nbt: CompoundNBT): Unit = robot.loadData(nbt) - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound): Unit = robot.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT): Unit = robot.loadForClient(nbt) - override def writeToNBTForClient(nbt: NBTTagCompound): Unit = robot.writeToNBTForClient(nbt) + override def saveForClient(nbt: CompoundNBT): Unit = robot.saveForClient(nbt) - override def getMaxRenderDistanceSquared: Double = robot.getMaxRenderDistanceSquared + @OnlyIn(Dist.CLIENT) + override def getViewDistance: Double = robot.getViewDistance override def getRenderBoundingBox: AxisAlignedBB = robot.getRenderBoundingBox - override def shouldRenderInPass(pass: Int): Boolean = robot.shouldRenderInPass(pass) - - override def markDirty(): Unit = robot.markDirty() + override def setChanged(): Unit = robot.setChanged() // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = robot.onAnalyze(player, side, hitX, hitY, hitZ) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = robot.onAnalyze(player, side, hitX, hitY, hitZ) // ----------------------------------------------------------------------- // @@ -223,89 +238,71 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo override def checkRedstoneInputChanged(): Unit = robot.checkRedstoneInputChanged() - /* TORO RedLogic - @Optional.Method(modid = Mods.IDs.RedLogic) - override def connects(wire: IWire, blockFace: Int, fromDirection: Int) = robot.connects(wire, blockFace, fromDirection) - - @Optional.Method(modid = Mods.IDs.RedLogic) - override def connectsAroundCorner(wire: IWire, blockFace: Int, fromDirection: Int) = robot.connectsAroundCorner(wire, blockFace, fromDirection) - - @Optional.Method(modid = Mods.IDs.RedLogic) - override def getBundledCableStrength(blockFace: Int, toDirection: Int) = robot.getBundledCableStrength(blockFace, toDirection) - - @Optional.Method(modid = Mods.IDs.RedLogic) - override def getEmittedSignalStrength(blockFace: Int, toDirection: Int) = robot.getEmittedSignalStrength(blockFace, toDirection) - - @Optional.Method(modid = Mods.IDs.RedLogic) - override def onBundledInputChanged() = robot.onBundledInputChanged() - - @Optional.Method(modid = Mods.IDs.RedLogic) - override def onRedstoneInputChanged() = robot.onRedstoneInputChanged() - */ - // ----------------------------------------------------------------------- // - override def pitch: EnumFacing = robot.pitch + override def pitch: Direction = robot.pitch - override def pitch_=(value: EnumFacing): Unit = robot.pitch_=(value) + override def pitch_=(value: Direction): Unit = robot.pitch_=(value) - override def yaw: EnumFacing = robot.yaw + override def yaw: Direction = robot.yaw - override def yaw_=(value: EnumFacing): Unit = robot.yaw_=(value) + override def yaw_=(value: Direction): Unit = robot.yaw_=(value) override def setFromEntityPitchAndYaw(entity: Entity): Boolean = robot.setFromEntityPitchAndYaw(entity) - override def setFromFacing(value: EnumFacing): Boolean = robot.setFromFacing(value) + override def setFromFacing(value: Direction): Boolean = robot.setFromFacing(value) override def invertRotation(): Boolean = robot.invertRotation() - override def facing: EnumFacing = robot.facing + override def facing: Direction = robot.facing - override def rotate(axis: EnumFacing): Boolean = robot.rotate(axis) + override def rotate(axis: Direction): Boolean = robot.rotate(axis) - override def toLocal(value: EnumFacing): EnumFacing = robot.toLocal(value) + override def toLocal(value: Direction): Direction = robot.toLocal(value) - override def toGlobal(value: EnumFacing): EnumFacing = robot.toGlobal(value) + override def toGlobal(value: Direction): Direction = robot.toGlobal(value) // ----------------------------------------------------------------------- // - override def getStackInSlot(i: Int): ItemStack = robot.getStackInSlot(i) + override def getItem(i: Int): ItemStack = robot.getItem(i) - override def decrStackSize(slot: Int, amount: Int): ItemStack = robot.decrStackSize(slot, amount) + override def removeItem(slot: Int, amount: Int): ItemStack = robot.removeItem(slot, amount) - override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = robot.setInventorySlotContents(slot, stack) + override def setItem(slot: Int, stack: ItemStack): Unit = robot.setItem(slot, stack) - override def removeStackFromSlot(slot: Int): ItemStack = robot.removeStackFromSlot(slot) + override def removeItemNoUpdate(slot: Int): ItemStack = robot.removeItemNoUpdate(slot) - override def openInventory(player: EntityPlayer): Unit = robot.openInventory(player) + override def startOpen(player: PlayerEntity): Unit = robot.startOpen(player) - override def closeInventory(player: EntityPlayer): Unit = robot.closeInventory(player) + override def stopOpen(player: PlayerEntity): Unit = robot.stopOpen(player) override def hasCustomName: Boolean = robot.hasCustomName - override def isUsableByPlayer(player: EntityPlayer): Boolean = robot.isUsableByPlayer(player) + override def stillValid(player: PlayerEntity): Boolean = robot.stillValid(player) + + override def forAllLoot(dst: Consumer[ItemStack]): Unit = robot.forAllLoot(dst) - override def dropSlot(slot: Int, count: Int, direction: Option[EnumFacing]): Boolean = robot.dropSlot(slot, count, direction) + override def dropSlot(slot: Int, count: Int, direction: Option[Direction]): Boolean = robot.dropSlot(slot, count, direction) override def dropAllSlots(): Unit = robot.dropAllSlots() - override def getInventoryStackLimit: Int = robot.getInventoryStackLimit + override def getMaxStackSize: Int = robot.getMaxStackSize override def componentSlot(address: String): Int = robot.componentSlot(address) - override def getName: String = robot.getName + override def getName: ITextComponent = robot.getName - override def getSizeInventory: Int = robot.getSizeInventory + override def getContainerSize: Int = robot.getContainerSize - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = robot.isItemValidForSlot(slot, stack) + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = robot.canPlaceItem(slot, stack) // ----------------------------------------------------------------------- // - override def canExtractItem(slot: Int, stack: ItemStack, side: EnumFacing): Boolean = robot.canExtractItem(slot, stack, side) + override def canTakeItemThroughFace(slot: Int, stack: ItemStack, side: Direction): Boolean = robot.canTakeItemThroughFace(slot, stack, side) - override def canInsertItem(slot: Int, stack: ItemStack, side: EnumFacing): Boolean = robot.canInsertItem(slot, stack, side) + override def canPlaceItemThroughFace(slot: Int, stack: ItemStack, side: Direction): Boolean = robot.canPlaceItemThroughFace(slot, stack, side) - override def getSlotsForFace(side: EnumFacing): Array[Int] = robot.getSlotsForFace(side) + override def getSlotsForFace(side: Direction): Array[Int] = robot.getSlotsForFace(side) // ----------------------------------------------------------------------- // @@ -323,15 +320,17 @@ class RobotProxy(val robot: Robot) extends traits.Computer with traits.PowerInfo // ----------------------------------------------------------------------- // - override def fill(resource: FluidStack, doFill: Boolean): Int = robot.fill(resource, doFill) + override def getTanks: Int = robot.getTanks + + override def getFluidInTank(tank: Int): FluidStack = robot.getFluidInTank(tank) - override def drain(resource: FluidStack, doDrain: Boolean): FluidStack = robot.drain(resource, doDrain) + override def getTankCapacity(tank: Int): Int = robot.getTankCapacity(tank) - override def drain(maxDrain: Int, doDrain: Boolean): FluidStack = robot.drain(maxDrain, doDrain) + override def isFluidValid(tank: Int, resource: FluidStack): Boolean = robot.isFluidValid(tank, resource) - def canFill(fluid: Fluid): Boolean = robot.canFill(fluid) + override def fill(resource: FluidStack, action: FluidAction): Int = robot.fill(resource, action) - def canDrain(fluid: Fluid): Boolean = robot.canDrain(fluid) + override def drain(resource: FluidStack, action: FluidAction): FluidStack = robot.drain(resource, action) - override def getTankProperties: Array[IFluidTankProperties] = robot.getTankProperties + override def drain(maxDrain: Int, action: FluidAction): FluidStack = robot.drain(maxDrain, action) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Screen.scala b/src/main/scala/li/cil/oc/common/tileentity/Screen.scala index 28233912ab..9c229d7992 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Screen.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Screen.scala @@ -5,30 +5,32 @@ import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network._ import li.cil.oc.client.gui import li.cil.oc.common.component.TextBuffer -import li.cil.oc.util.BlockPosition import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs +import li.cil.oc.util.BlockPosition import li.cil.oc.util.Color import li.cil.oc.util.ExtendedWorld._ import net.minecraft.client.Minecraft import net.minecraft.entity.Entity -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.projectile.EntityArrow -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.projectile.ArrowEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction import net.minecraft.util.math.AxisAlignedBB -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import scala.collection.mutable import scala.language.postfixOps -class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with traits.Rotatable with traits.RedstoneAware with traits.Colored with Analyzable with Ordered[Screen] { - def this() = this(0) +class Screen(selfType: TileEntityType[_ <: Screen], var tier: Int) extends TileEntity(selfType) with traits.TextBuffer with SidedEnvironment with traits.Rotatable with traits.RedstoneAware with traits.Colored with Analyzable with Ordered[Screen] { + def this(selfType: TileEntityType[_ <: Screen]) = this(selfType, 0) // Enable redstone functionality. _isOutputEnabled = true - override def validFacings = EnumFacing.values + override def validFacings = Direction.values // ----------------------------------------------------------------------- // @@ -57,17 +59,17 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with var invertTouchMode = false - private val arrows = mutable.Set.empty[EntityArrow] + private val arrows = mutable.Set.empty[ArrowEntity] private val lastWalked = mutable.WeakHashMap.empty[Entity, (Int, Int)] setColor(Color.rgbValues(Color.byTier(tier))) - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing) = side != facing + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction) = side != facing // Allow connections from front for keyboards, and keyboards only... - override def sidedNode(side: EnumFacing) = if (side != facing || (getWorld.isBlockLoaded(getPos.offset(side)) && getWorld.getTileEntity(getPos.offset(side)).isInstanceOf[Keyboard])) node else null + override def sidedNode(side: Direction) = if (side != facing || (getLevel.isLoaded(getBlockPos.relative(side)) && getLevel.getBlockEntity(getBlockPos.relative(side)).isInstanceOf[Keyboard])) node else null // ----------------------------------------------------------------------- // @@ -80,9 +82,9 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with } def hasKeyboard = screens.exists(screen => - EnumFacing.values.map(side => (side, { + Direction.values.map(side => (side, { val blockPos = BlockPosition(screen).offset(side) - if (getWorld.blockExists(blockPos)) getWorld.getTileEntity(blockPos) + if (getLevel.blockExists(blockPos)) getLevel.getBlockEntity(blockPos) else null })).exists { case (side, keyboard: Keyboard) => keyboard.hasNodeOnSide(side.getOpposite) @@ -102,8 +104,8 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with def toScreenCoordinates(hitX: Double, hitY: Double, hitZ: Double): (Boolean, Option[(Double, Double)]) = { // Compute absolute position of the click on the face, measured in blocks. - def dot(f: EnumFacing) = f.getFrontOffsetX * hitX + f.getFrontOffsetY * hitY + f.getFrontOffsetZ * hitZ - val (hx, hy) = (dot(toGlobal(EnumFacing.EAST)), dot(toGlobal(EnumFacing.UP))) + def dot(f: Direction) = f.getStepX * hitX + f.getStepY * hitY + f.getStepZ * hitZ + val (hx, hy) = (dot(toGlobal(Direction.EAST)), dot(toGlobal(Direction.UP))) val tx = if (hx < 0) 1 + hx else hx val ty = 1 - (if (hy < 0) 1 + hy else hy) val (lx, ly) = localPosition @@ -114,7 +116,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with if (ax <= border || ay <= border || ax >= width - border || ay >= height - border) { return (false, None) } - if (!getWorld.isRemote) return (true, None) + if (!getLevel.isClientSide) return (true, None) val (iw, ih) = (width - border * 2, height - border * 2) val (rx, ry) = ((ax - border) / iw, (ay - border) / ih) @@ -170,15 +172,15 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with origin.lastWalked.put(entity, localPosition) match { case Some((oldX, oldY)) if oldX == x && oldY == y => // Ignore case _ => entity match { - case player: EntityPlayer if Settings.get.inputUsername => - origin.node.sendToReachable("computer.signal", "walk", Int.box(x + 1), Int.box(height - y), player.getName) + case player: PlayerEntity if Settings.get.inputUsername => + origin.node.sendToReachable("computer.signal", "walk", Int.box(x + 1), Int.box(height - y), player.getName.getString) case _ => origin.node.sendToReachable("computer.signal", "walk", Int.box(x + 1), Int.box(height - y)) } } } - def shot(arrow: EntityArrow) { + def shot(arrow: ArrowEntity) { arrows.add(arrow) } @@ -198,7 +200,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with val lpos = project(current) def tryQueue(dx: Int, dy: Int) { val npos = unproject(lpos.x + dx, lpos.y + dy, lpos.z) - if (getWorld.blockExists(npos)) getWorld.getTileEntity(npos) match { + if (getLevel.blockExists(npos)) getLevel.getBlockEntity(npos) match { case s: Screen if s.pitch == pitch && s.yaw == yaw && pending.add(s) => queue += s case _ => // Ignore. } @@ -218,12 +220,8 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with pending.remove(screen) queue += screen } - if (isClient) { - val bounds = current.origin.getRenderBoundingBox - getWorld.markBlockRangeForRenderUpdate(bounds.minX.toInt, bounds.minY.toInt, bounds.minZ.toInt, - bounds.maxX.toInt, bounds.maxY.toInt, bounds.maxZ.toInt) - } } + if (isClient) updateMergedModels() // Update visibility after everything is done, to avoid noise. queue.foreach(screen => { val buffer = screen.buffer @@ -250,11 +248,11 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with } if (arrows.nonEmpty) { for (arrow <- arrows) { - val hitX = arrow.posX - x - val hitY = arrow.posY - y - val hitZ = arrow.posZ - z - arrow.shootingEntity match { - case player: EntityPlayer if player == Minecraft.getMinecraft.player => click(hitX, hitY, hitZ) + val hitX = arrow.getX - x + val hitY = arrow.getY - y + val hitZ = arrow.getZ - z + arrow.getOwner match { + case player: PlayerEntity if player == Minecraft.getInstance.player => click(hitX, hitY, hitZ) case _ => } } @@ -262,6 +260,16 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with } } + private def updateMergedModels() { + if (getLevel == Minecraft.getInstance.level) { + val renderer = Minecraft.getInstance.levelRenderer + screens.foreach(screen => { + val pos = screen.getBlockPos + renderer.setSectionDirty(pos.getX >> 4, pos.getY >> 4, pos.getZ >> 4) + }) + } + } + private def isClientReadyForMultiBlockCheck = if (delayUntilCheckForMultiBlock > 0) { delayUntilCheckForMultiBlock -= 1 false @@ -271,9 +279,8 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with super.dispose() screens.clone().foreach(_.checkMultiBlock()) if (isClient) { - Minecraft.getMinecraft.currentScreen match { - case screenGui: gui.Screen if screenGui.buffer == buffer => - Minecraft.getMinecraft.displayGuiScreen(null) + Minecraft.getInstance.screen match { + case screenGui: gui.Screen if screenGui.buffer == buffer => screenGui.onClose() case _ => } } @@ -290,37 +297,37 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with private final val HadRedstoneInputTag = Settings.namespace + "hadRedstoneInput" private final val InvertTouchModeTag = Settings.namespace + "invertTouchMode" - override def readFromNBTForServer(nbt: NBTTagCompound) { + override def loadForServer(nbt: CompoundNBT) { tier = nbt.getByte(TierTag) max 0 min 2 setColor(Color.rgbValues(Color.byTier(tier))) - super.readFromNBTForServer(nbt) + super.loadForServer(nbt) hadRedstoneInput = nbt.getBoolean(HadRedstoneInputTag) invertTouchMode = nbt.getBoolean(InvertTouchModeTag) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - nbt.setByte(TierTag, tier.toByte) - super.writeToNBTForServer(nbt) - nbt.setBoolean(HadRedstoneInputTag, hadRedstoneInput) - nbt.setBoolean(InvertTouchModeTag, invertTouchMode) + override def saveForServer(nbt: CompoundNBT) { + nbt.putByte(TierTag, tier.toByte) + super.saveForServer(nbt) + nbt.putBoolean(HadRedstoneInputTag, hadRedstoneInput) + nbt.putBoolean(InvertTouchModeTag, invertTouchMode) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound) { + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT) { tier = nbt.getByte(TierTag) max 0 min 2 - super.readFromNBTForClient(nbt) + super.loadForClient(nbt) invertTouchMode = nbt.getBoolean(InvertTouchModeTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - nbt.setByte(TierTag, tier.toByte) - super.writeToNBTForClient(nbt) - nbt.setBoolean(InvertTouchModeTag, invertTouchMode) + override def saveForClient(nbt: CompoundNBT) { + nbt.putByte(TierTag, tier.toByte) + super.saveForClient(nbt) + nbt.putBoolean(InvertTouchModeTag, invertTouchMode) } // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) override def getRenderBoundingBox = if ((width == 1 && height == 1) || !isOrigin) super.getRenderBoundingBox else cachedBounds match { @@ -338,12 +345,12 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with b } - @SideOnly(Side.CLIENT) - override def getMaxRenderDistanceSquared = if (isOrigin) super.getMaxRenderDistanceSquared else 0 + @OnlyIn(Dist.CLIENT) + override def getViewDistance = if (isOrigin) super.getViewDistance else 0 // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(origin.node) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(origin.node) override protected def onRedstoneInputChanged(args: RedstoneChangedEventArgs) { super.onRedstoneInputChanged(args) @@ -374,7 +381,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with val opos = project(origin) def tryMergeTowards(dx: Int, dy: Int) = { val npos = unproject(opos.x + dx, opos.y + dy, opos.z) - getWorld.blockExists(npos) && (getWorld.getTileEntity(npos) match { + getLevel.blockExists(npos) && (getLevel.getBlockEntity(npos) match { case s: Screen if s.tier == tier && s.pitch == pitch && s.getColor == getColor && s.yaw == yaw && !screens.contains(s) => val spos = project(s.origin) val canMergeAlongX = spos.y == opos.y && s.height == height && s.width + width <= Settings.get.maxScreenWidth @@ -408,12 +415,12 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with } private def project(t: Screen) = { - def dot(f: EnumFacing, s: Screen) = f.getFrontOffsetX * s.x + f.getFrontOffsetY * s.y + f.getFrontOffsetZ * s.z - BlockPosition(dot(toGlobal(EnumFacing.EAST), t), dot(toGlobal(EnumFacing.UP), t), dot(toGlobal(EnumFacing.SOUTH), t)) + def dot(f: Direction, s: Screen) = f.getStepX * s.x + f.getStepY * s.y + f.getStepZ * s.z + BlockPosition(dot(toGlobal(Direction.EAST), t), dot(toGlobal(Direction.UP), t), dot(toGlobal(Direction.SOUTH), t)) } private def unproject(x: Int, y: Int, z: Int) = { - def dot(f: EnumFacing) = f.getFrontOffsetX * x + f.getFrontOffsetY * y + f.getFrontOffsetZ * z - BlockPosition(dot(toLocal(EnumFacing.EAST)), dot(toLocal(EnumFacing.UP)), dot(toLocal(EnumFacing.SOUTH))) + def dot(f: Direction) = f.getStepX * x + f.getStepY * y + f.getStepZ * z + BlockPosition(dot(toLocal(Direction.EAST)), dot(toLocal(Direction.UP)), dot(toLocal(Direction.SOUTH))) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/TileEntityTypes.java b/src/main/scala/li/cil/oc/common/tileentity/TileEntityTypes.java new file mode 100644 index 0000000000..0b3e3de4a0 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/tileentity/TileEntityTypes.java @@ -0,0 +1,118 @@ +package li.cil.oc.common.tileentity; + +import li.cil.oc.OpenComputers; +import li.cil.oc.Constants; +import li.cil.oc.api.Items; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.ObjectHolder; + +@ObjectHolder("opencomputers") +public final class TileEntityTypes { + public static final TileEntityType ADAPTER = null; + public static final TileEntityType ASSEMBLER = null; + public static final TileEntityType CABLE = null; + public static final TileEntityType CAPACITOR = null; + public static final TileEntityType CARPETED_CAPACITOR = null; + public static final TileEntityType CASE = null; + public static final TileEntityType CHARGER = null; + public static final TileEntityType DISASSEMBLER = null; + public static final TileEntityType DISK_DRIVE = null; + public static final TileEntityType GEOLYZER = null; + public static final TileEntityType HOLOGRAM = null; + public static final TileEntityType KEYBOARD = null; + public static final TileEntityType MICROCONTROLLER = null; + public static final TileEntityType MOTION_SENSOR = null; + public static final TileEntityType NET_SPLITTER = null; + public static final TileEntityType POWER_CONVERTER = null; + public static final TileEntityType POWER_DISTRIBUTOR = null; + public static final TileEntityType PRINT = null; + public static final TileEntityType PRINTER = null; + public static final TileEntityType RACK = null; + public static final TileEntityType RAID = null; + public static final TileEntityType REDSTONE_IO = null; + public static final TileEntityType RELAY = null; + // We use the RobotProxy instead of Robot here because those are the ones actually found in the world. + // Beware of TileEntityType.create for this as it will construct a new, empty robot. + public static final TileEntityType ROBOT = null; + public static final TileEntityType SCREEN = null; + public static final TileEntityType TRANSPOSER = null; + public static final TileEntityType WAYPOINT = null; + + @SubscribeEvent + public static void registerTileEntities(RegistryEvent.Register> e) { + register(e.getRegistry(), "adapter", TileEntityType.Builder.of(() -> new Adapter(ADAPTER), + Items.get(Constants.BlockName$.MODULE$.Adapter()).block())); + register(e.getRegistry(), "assembler", TileEntityType.Builder.of(() -> new Assembler(ASSEMBLER), + Items.get(Constants.BlockName$.MODULE$.Assembler()).block())); + register(e.getRegistry(), "cable", TileEntityType.Builder.of(() -> new Cable(CABLE), + Items.get(Constants.BlockName$.MODULE$.Cable()).block())); + register(e.getRegistry(), "capacitor", TileEntityType.Builder.of(() -> new Capacitor(CAPACITOR), + Items.get(Constants.BlockName$.MODULE$.Capacitor()).block())); + register(e.getRegistry(), "carpeted_capacitor", TileEntityType.Builder.of(() -> new CarpetedCapacitor(CARPETED_CAPACITOR), + Items.get(Constants.BlockName$.MODULE$.CarpetedCapacitor()).block())); + register(e.getRegistry(), "case", TileEntityType.Builder.of(() -> new Case(CASE), + Items.get(Constants.BlockName$.MODULE$.CaseCreative()).block(), + Items.get(Constants.BlockName$.MODULE$.CaseTier1()).block(), + Items.get(Constants.BlockName$.MODULE$.CaseTier2()).block(), + Items.get(Constants.BlockName$.MODULE$.CaseTier3()).block())); + register(e.getRegistry(), "charger", TileEntityType.Builder.of(() -> new Charger(CHARGER), + Items.get(Constants.BlockName$.MODULE$.Charger()).block())); + register(e.getRegistry(), "disassembler", TileEntityType.Builder.of(() -> new Disassembler(DISASSEMBLER), + Items.get(Constants.BlockName$.MODULE$.Disassembler()).block())); + register(e.getRegistry(), "disk_drive", TileEntityType.Builder.of(() -> new DiskDrive(DISK_DRIVE), + Items.get(Constants.BlockName$.MODULE$.DiskDrive()).block())); + register(e.getRegistry(), "geolyzer", TileEntityType.Builder.of(() -> new Geolyzer(GEOLYZER), + Items.get(Constants.BlockName$.MODULE$.Geolyzer()).block())); + register(e.getRegistry(), "hologram", TileEntityType.Builder.of(() -> new Hologram(HOLOGRAM), + Items.get(Constants.BlockName$.MODULE$.HologramTier1()).block(), + Items.get(Constants.BlockName$.MODULE$.HologramTier2()).block())); + register(e.getRegistry(), "keyboard", TileEntityType.Builder.of(() -> new Keyboard(KEYBOARD), + Items.get(Constants.BlockName$.MODULE$.Keyboard()).block())); + register(e.getRegistry(), "microcontroller", TileEntityType.Builder.of(() -> new Microcontroller(MICROCONTROLLER), + Items.get(Constants.BlockName$.MODULE$.Microcontroller()).block())); + register(e.getRegistry(), "motion_sensor", TileEntityType.Builder.of(() -> new MotionSensor(MOTION_SENSOR), + Items.get(Constants.BlockName$.MODULE$.MotionSensor()).block())); + register(e.getRegistry(), "net_splitter", TileEntityType.Builder.of(() -> new NetSplitter(NET_SPLITTER), + Items.get(Constants.BlockName$.MODULE$.NetSplitter()).block())); + register(e.getRegistry(), "power_converter", TileEntityType.Builder.of(() -> new PowerConverter(POWER_CONVERTER), + Items.get(Constants.BlockName$.MODULE$.PowerConverter()).block())); + register(e.getRegistry(), "power_distributor", TileEntityType.Builder.of(() -> new PowerDistributor(POWER_DISTRIBUTOR), + Items.get(Constants.BlockName$.MODULE$.PowerDistributor()).block())); + register(e.getRegistry(), "print", TileEntityType.Builder.of(() -> new Print(PRINT), + Items.get(Constants.BlockName$.MODULE$.Print()).block())); + register(e.getRegistry(), "printer", TileEntityType.Builder.of(() -> new Printer(PRINTER), + Items.get(Constants.BlockName$.MODULE$.Printer()).block())); + register(e.getRegistry(), "rack", TileEntityType.Builder.of(() -> new Rack(RACK), + Items.get(Constants.BlockName$.MODULE$.Rack()).block())); + register(e.getRegistry(), "raid", TileEntityType.Builder.of(() -> new Raid(RAID), + Items.get(Constants.BlockName$.MODULE$.Raid()).block())); + register(e.getRegistry(), "redstone_io", TileEntityType.Builder.of(() -> new Redstone(REDSTONE_IO), + Items.get(Constants.BlockName$.MODULE$.Redstone()).block())); + register(e.getRegistry(), "relay", TileEntityType.Builder.of(() -> new Relay(RELAY), + Items.get(Constants.BlockName$.MODULE$.Relay()).block())); + register(e.getRegistry(), "robot", TileEntityType.Builder.of(() -> new RobotProxy(ROBOT), + Items.get(Constants.BlockName$.MODULE$.Robot()).block())); + register(e.getRegistry(), "screen", TileEntityType.Builder.of(() -> new Screen(SCREEN), + Items.get(Constants.BlockName$.MODULE$.ScreenTier1()).block(), + Items.get(Constants.BlockName$.MODULE$.ScreenTier2()).block(), + Items.get(Constants.BlockName$.MODULE$.ScreenTier3()).block())); + register(e.getRegistry(), "transposer", TileEntityType.Builder.of(() -> new Transposer(TRANSPOSER), + Items.get(Constants.BlockName$.MODULE$.Transposer()).block())); + register(e.getRegistry(), "waypoint", TileEntityType.Builder.of(() -> new Waypoint(WAYPOINT), + Items.get(Constants.BlockName$.MODULE$.Waypoint()).block())); + } + + private static void register(IForgeRegistry> registry, String name, TileEntityType.Builder builder) { + TileEntityType type = builder.build(null); + type.setRegistryName(new ResourceLocation(OpenComputers.ID(), name)); + registry.register(type); + } + + private TileEntityTypes() { + throw new Error(); + } +} diff --git a/src/main/scala/li/cil/oc/common/tileentity/Transposer.scala b/src/main/scala/li/cil/oc/common/tileentity/Transposer.scala index 78a7fc8e9e..a1957e9b54 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Transposer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Transposer.scala @@ -1,9 +1,11 @@ package li.cil.oc.common.tileentity import li.cil.oc.server.component -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType -class Transposer extends traits.Environment { +class Transposer(selfType: TileEntityType[_ <: Transposer]) extends TileEntity(selfType) with traits.Environment { val transposer = new component.Transposer.Block(this) def node = transposer.node @@ -11,13 +13,13 @@ class Transposer extends traits.Environment { // Used on client side to check whether to render activity indicators. var lastOperation = 0L - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - transposer.load(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + transposer.loadData(nbt) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - transposer.save(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + transposer.saveData(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Waypoint.scala b/src/main/scala/li/cil/oc/common/tileentity/Waypoint.scala index 058a291765..0f69894c79 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Waypoint.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Waypoint.scala @@ -8,19 +8,22 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.network.Visibility import li.cil.oc.common.EventHandler import li.cil.oc.server.network.Waypoints -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.{EnumFacing, EnumParticleTypes} -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly - -class Waypoint extends traits.Environment with traits.Rotatable with traits.RedstoneAware with traits.Tickable { +import net.minecraft.nbt.CompoundNBT +import net.minecraft.particles.ParticleTypes +import net.minecraft.tileentity.TileEntity +import net.minecraft.tileentity.TileEntityType +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn + +class Waypoint(selfType: TileEntityType[_ <: Waypoint]) extends TileEntity(selfType) with traits.Environment with traits.Rotatable with traits.RedstoneAware with traits.Tickable { val node = api.Network.newNode(this, Visibility.Network). withComponent("waypoint"). create() var label = "" - override def validFacings: Array[EnumFacing] = EnumFacing.values + override def validFacings: Array[Direction] = Direction.values // ----------------------------------------------------------------------- // @@ -39,14 +42,14 @@ class Waypoint extends traits.Environment with traits.Rotatable with traits.Reds override def updateEntity(): Unit = { super.updateEntity() if (isClient) { - val origin = position.toVec3.addVector(facing.getFrontOffsetX * 0.5, facing.getFrontOffsetY * 0.5, facing.getFrontOffsetZ * 0.5) - val dx = (getWorld.rand.nextFloat() - 0.5f) * 0.8f - val dy = (getWorld.rand.nextFloat() - 0.5f) * 0.8f - val dz = (getWorld.rand.nextFloat() - 0.5f) * 0.8f - val vx = (getWorld.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetX * 0.3f - val vy = (getWorld.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetY * 0.3f - 0.5f - val vz = (getWorld.rand.nextFloat() - 0.5f) * 0.2f + facing.getFrontOffsetZ * 0.3f - getWorld.spawnParticle(EnumParticleTypes.PORTAL, origin.x + dx, origin.y + dy, origin.z + dz, vx, vy, vz) + val origin = position.toVec3.add(facing.getStepX * 0.5, facing.getStepY * 0.5, facing.getStepZ * 0.5) + val dx = (getLevel.random.nextFloat() - 0.5f) * 0.8f + val dy = (getLevel.random.nextFloat() - 0.5f) * 0.8f + val dz = (getLevel.random.nextFloat() - 0.5f) * 0.8f + val vx = (getLevel.random.nextFloat() - 0.5f) * 0.2f + facing.getStepX * 0.3f + val vy = (getLevel.random.nextFloat() - 0.5f) * 0.2f + facing.getStepY * 0.3f - 0.5f + val vz = (getLevel.random.nextFloat() - 0.5f) * 0.2f + facing.getStepZ * 0.3f + getLevel.addParticle(ParticleTypes.PORTAL, origin.x + dx, origin.y + dy, origin.z + dz, vx, vy, vz) } } @@ -64,24 +67,24 @@ class Waypoint extends traits.Environment with traits.Rotatable with traits.Reds private final val LabelTag = Settings.namespace + "label" - override def readFromNBTForServer(nbt: NBTTagCompound): Unit = { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT): Unit = { + super.loadForServer(nbt) label = nbt.getString(LabelTag) } - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - super.writeToNBTForServer(nbt) - nbt.setString(LabelTag, label) + override def saveForServer(nbt: CompoundNBT): Unit = { + super.saveForServer(nbt) + nbt.putString(LabelTag, label) } - @SideOnly(Side.CLIENT) override - def readFromNBTForClient(nbt: NBTTagCompound): Unit = { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) override + def loadForClient(nbt: CompoundNBT): Unit = { + super.loadForClient(nbt) label = nbt.getString(LabelTag) } - override def writeToNBTForClient(nbt: NBTTagCompound): Unit = { - super.writeToNBTForClient(nbt) - nbt.setString(LabelTag, label) + override def saveForClient(nbt: CompoundNBT): Unit = { + super.saveForClient(nbt) + nbt.putString(LabelTag, label) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/BundledRedstoneAware.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/BundledRedstoneAware.scala index ae3e6c75a9..8727a627ef 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/BundledRedstoneAware.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/BundledRedstoneAware.scala @@ -3,19 +3,16 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.Settings import li.cil.oc.integration.util.BundledRedstone import li.cil.oc.util.ExtendedNBT._ +import li.cil.oc.util.RotationHelper import li.cil.oc.integration.Mods import mrtjp.projectred.api.IBundledTile -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagIntArray -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.IntArrayNBT +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.common.Optional import java.util -import li.cil.oc.integration.charset.{CapabilitiesCharset, ModCharset} -import net.minecraftforge.common.capabilities.Capability - -trait BundledRedstoneAware extends RedstoneAware with IBundledTile { +trait BundledRedstoneAware extends RedstoneAware { protected[tileentity] val _bundledInput: Array[Array[Int]] = Array.fill(6)(Array.fill(16)(-1)) @@ -42,7 +39,7 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { (0 until 6).map(side => (0 until 16).map(color => _bundledInput(side)(color) max _rednetInput(side)(color) max 0).toArray).toArray } - private def checkSide(side: EnumFacing): Int = { + private def checkSide(side: Direction): Int = { val index = side.ordinal if (index >= 6) throw new IndexOutOfBoundsException(s"Bad side $side") index @@ -53,14 +50,14 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { color } - def getBundledInput(side: EnumFacing): Array[Int] = { + def getBundledInput(side: Direction): Array[Int] = { val sideIndex = checkSide(side) val bundled = _bundledInput(sideIndex) val rednet = _rednetInput(sideIndex) - (bundled, rednet).zipped.map((a, b) => a max b max 0) + bundled.lazyZip(rednet).map((a, b) => a max b max 0) } - def getBundledInput(side: EnumFacing, color: Int): Int = { + def getBundledInput(side: Direction, color: Int): Int = { val sideIndex = checkSide(side) val colorIndex = checkColor(color) val bundled = _bundledInput(sideIndex)(colorIndex) @@ -68,20 +65,20 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { bundled max rednet max 0 } - def setBundledInput(side: EnumFacing, color: Int, newValue: Int): Unit = { + def setBundledInput(side: Direction, color: Int, newValue: Int): Unit = { updateInput(_bundledInput, side, color, newValue) } - def setBundledInput(side: EnumFacing, newBundledInput: Array[Int]): Unit = { + def setBundledInput(side: Direction, newBundledInput: Array[Int]): Unit = { for (color <- 0 until 16) { val value = if (newBundledInput == null || color >= newBundledInput.length) 0 else newBundledInput(color) setBundledInput(side, color, value) } } - def setRednetInput(side: EnumFacing, color: Int, value: Int): Unit = updateInput(_rednetInput, side, color, value) + def setRednetInput(side: Direction, color: Int, value: Int): Unit = updateInput(_rednetInput, side, color, value) - def updateInput(inputs: Array[Array[Int]], side: EnumFacing, color: Int, newValue: Int): Unit = { + def updateInput(inputs: Array[Array[Int]], side: Direction, color: Int, newValue: Int): Unit = { val sideIndex = checkSide(side) val colorIndex = checkColor(color) val oldValue = inputs(sideIndex)(colorIndex) @@ -95,17 +92,17 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { def getBundledOutput: Array[Array[Int]] = _bundledInput - def getBundledOutput(side: EnumFacing): Array[Int] = _bundledOutput(checkSide(toLocal(side))) + def getBundledOutput(side: Direction): Array[Int] = _bundledOutput(checkSide(toLocal(side))) - def getBundledOutput(side: EnumFacing, color: Int): Int = getBundledOutput(side)(checkColor(color)) + def getBundledOutput(side: Direction, color: Int): Int = getBundledOutput(side)(checkColor(color)) - def setBundledOutput(side: EnumFacing, color: Int, value: Int): Boolean = if (value != getBundledOutput(side, color)) { + def setBundledOutput(side: Direction, color: Int, value: Int): Boolean = if (value != getBundledOutput(side, color)) { _bundledOutput(checkSide(toLocal(side)))(checkColor(color)) = value onRedstoneOutputChanged(side) true } else false - def setBundledOutput(side: EnumFacing, values: util.Map[_, _]): Boolean = { + def setBundledOutput(side: Direction, values: util.Map[_, _]): Boolean = { val sideIndex = toLocal(side).ordinal var changed: Boolean = false (0 until 16).foreach(color => { @@ -127,7 +124,7 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { def setBundledOutput(values: util.Map[_, _]): Boolean = { var changed: Boolean = false - EnumFacing.values.foreach(side => { + Direction.values.foreach(side => { val sideIndex = toLocal(side).ordinal // due to a bug in our jnlua layer, I cannot loop the map getObjectFuzzy(values, sideIndex) match { @@ -140,7 +137,7 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { // ----------------------------------------------------------------------- // - override def updateRedstoneInput(side: EnumFacing) { + override def updateRedstoneInput(side: Direction) { super.updateRedstoneInput(side) setBundledInput(side, BundledRedstone.computeBundledInput(position, side)) } @@ -151,26 +148,26 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { private final val BundledOutputTag = Settings.namespace + "rs.bundledOutput" private final val RednetInputTag = Settings.namespace + "rs.rednetInput" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) - nbt.getTagList(BundledInputTag, NBT.TAG_INT_ARRAY).toArray[NBTTagIntArray]. - map(_.getIntArray).zipWithIndex.foreach { + nbt.getList(BundledInputTag, NBT.TAG_INT_ARRAY).toTagArray[IntArrayNBT]. + map(_.getAsIntArray).zipWithIndex.foreach { case (input, index) if index < _bundledInput.length => val safeLength = input.length min _bundledInput(index).length input.copyToArray(_bundledInput(index), 0, safeLength) case _ => } - nbt.getTagList(BundledOutputTag, NBT.TAG_INT_ARRAY).toArray[NBTTagIntArray]. - map(_.getIntArray).zipWithIndex.foreach { + nbt.getList(BundledOutputTag, NBT.TAG_INT_ARRAY).toTagArray[IntArrayNBT]. + map(_.getAsIntArray).zipWithIndex.foreach { case (input, index) if index < _bundledOutput.length => val safeLength = input.length min _bundledOutput(index).length input.copyToArray(_bundledOutput(index), 0, safeLength) case _ => } - nbt.getTagList(RednetInputTag, NBT.TAG_INT_ARRAY).toArray[NBTTagIntArray]. - map(_.getIntArray).zipWithIndex.foreach { + nbt.getList(RednetInputTag, NBT.TAG_INT_ARRAY).toTagArray[IntArrayNBT]. + map(_.getAsIntArray).zipWithIndex.foreach { case (input, index) if index < _rednetInput.length => val safeLength = input.length min _rednetInput(index).length input.copyToArray(_rednetInput(index), 0, safeLength) @@ -178,34 +175,12 @@ trait BundledRedstoneAware extends RedstoneAware with IBundledTile { } } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) nbt.setNewTagList(BundledInputTag, _bundledInput.view) nbt.setNewTagList(BundledOutputTag, _bundledOutput.view) nbt.setNewTagList(RednetInputTag, _rednetInput.view) } - - override def hasCapability(capability: Capability[_], side: EnumFacing): Boolean = { - if (capability == CapabilitiesCharset.BUNDLED_EMITTER || capability == CapabilitiesCharset.BUNDLED_RECEIVER) { - true - } else { - super.hasCapability(capability, side) - } - } - - override def getCapability[T](capability: Capability[T], side: EnumFacing): T = { - if (capability == CapabilitiesCharset.BUNDLED_EMITTER || capability == CapabilitiesCharset.BUNDLED_RECEIVER) { - new ModCharset.BundledRedstoneView(getBundledOutput(side), () => setBundledInput(side, BundledRedstone.computeBundledInput(position, side))).asInstanceOf[T] - } else { - super.getCapability(capability, side) - } - } - - @Optional.Method(modid = Mods.IDs.ProjectRedTransmission) - override def canConnectBundled(side: Int): Boolean = isOutputEnabled - - @Optional.Method(modid = Mods.IDs.ProjectRedTransmission) - override def getBundledSignal(side: Int): Array[Byte] = getBundledOutput(EnumFacing.getFront(side)).map(value => math.min(math.max(value, 0), 255).toByte) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Colored.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Colored.scala index 66129b6e5a..9d68f9b9f9 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Colored.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Colored.scala @@ -4,10 +4,10 @@ import li.cil.oc.Settings import li.cil.oc.api.internal import li.cil.oc.server.PacketSender import li.cil.oc.util.Color -import net.minecraft.item.EnumDyeColor -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.item.DyeColor +import net.minecraft.nbt.CompoundNBT +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn trait Colored extends TileEntity with internal.Colored { private var _color = 0 @@ -24,7 +24,7 @@ trait Colored extends TileEntity with internal.Colored { override def controlsConnectivity = false protected def onColorChanged() { - if (getWorld != null && isServer) { + if (getLevel != null && isServer) { PacketSender.sendColorChange(this) } } @@ -34,29 +34,29 @@ trait Colored extends TileEntity with internal.Colored { private final val RenderColorTag = Settings.namespace + "renderColorRGB" private final val RenderColorTagCompat = Settings.namespace + "renderColor" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - if (nbt.hasKey(RenderColorTagCompat)) { - _color = Color.rgbValues(EnumDyeColor.byMetadata(nbt.getInteger(RenderColorTagCompat))) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + if (nbt.contains(RenderColorTagCompat)) { + _color = Color.rgbValues(DyeColor.byId(nbt.getInt(RenderColorTagCompat))) } - if (nbt.hasKey(RenderColorTag)) { - _color = nbt.getInteger(RenderColorTag) + if (nbt.contains(RenderColorTag)) { + _color = nbt.getInt(RenderColorTag) } } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setInteger(RenderColorTag, _color) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + nbt.putInt(RenderColorTag, _color) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) - _color = nbt.getInteger(RenderColorTag) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) + _color = nbt.getInt(RenderColorTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setInteger(RenderColorTag, _color) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putInt(RenderColorTag, _color) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/ComponentInventory.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/ComponentInventory.scala index af21bd4945..a8297148e9 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/ComponentInventory.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/ComponentInventory.scala @@ -9,12 +9,13 @@ import li.cil.oc.util.ExtendedInventory._ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.ICapabilityProvider -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import scala.collection.mutable @@ -26,8 +27,8 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo // Cache changes to inventory slots on the client side to avoid recreating // components when we don't have to and the slots are just cleared by MC // temporarily. - private lazy val pendingRemovalsActual = mutable.ArrayBuffer.fill(getSizeInventory)(EmptyStack: StackOption) - private lazy val pendingAddsActual = mutable.ArrayBuffer.fill(getSizeInventory)(EmptyStack: StackOption) + private lazy val pendingRemovalsActual = mutable.ArrayBuffer.fill(getContainerSize)(EmptyStack: StackOption) + private lazy val pendingAddsActual = mutable.ArrayBuffer.fill(getContainerSize)(EmptyStack: StackOption) private var updateScheduled = false def pendingRemovals = { adjustSize(pendingRemovalsActual) @@ -39,12 +40,12 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo } private def adjustSize(buffer: mutable.ArrayBuffer[StackOption]): Unit = { - val delta = buffer.length - getSizeInventory + val delta = buffer.length - getContainerSize if (delta > 0) { buffer.remove(buffer.length - delta, delta) } else if (delta < 0) { - buffer.sizeHint(getSizeInventory) + buffer.sizeHint(getContainerSize) for (i <- 0 until -delta) { buffer += EmptyStack } @@ -56,17 +57,17 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo for (slot <- this.indices) { (pendingRemovals(slot), pendingAdds(slot)) match { case (SomeStack(removed), SomeStack(added)) => - if (!removed.isItemEqual(added) || !ItemStack.areItemStackTagsEqual(removed, added)) { + if (!removed.sameItem(added) || !ItemStack.tagMatches(removed, added)) { super.onItemRemoved(slot, removed) super.onItemAdded(slot, added) - markDirty() + setChanged() } // else: No change, ignore. case (SomeStack(removed), EmptyStack) => super.onItemRemoved(slot, removed) - markDirty() + setChanged() case (EmptyStack, SomeStack(added)) => super.onItemAdded(slot, added) - markDirty() + setChanged() case _ => // No change. } @@ -86,7 +87,7 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo if (isServer) super.onItemAdded(slot, stack) else { pendingRemovals(slot) match { - case SomeStack(removed) if removed.isItemEqual(stack) && ItemStack.areItemStackTagsEqual(removed, stack) => + case SomeStack(removed) if removed.sameItem(stack) && ItemStack.tagMatches(removed, stack) => // Reverted to original state. pendingAdds(slot) = EmptyStack pendingRemovals(slot) = EmptyStack @@ -153,37 +154,31 @@ trait ComponentInventory extends Environment with Inventory with inventory.Compo } } - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { val localFacing = this match { case rotatable: Rotatable => rotatable.toLocal(facing) case _ => facing } - super.hasCapability(capability, facing) || components.exists { - case Some(component: ICapabilityProvider) => component.hasCapability(capability, localFacing) - case _ => false - } - } - - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { - val localFacing = this match { - case rotatable: Rotatable => rotatable.toLocal(facing) - case _ => facing + for (curr <- components) curr match { + case Some(comp: ICapabilityProvider) => { + val cap = comp.getCapability(capability, localFacing) + if (cap.isPresent) return cap + } + case _ => } - (if (super.hasCapability(capability, facing)) Option(super.getCapability(capability, facing)) else None).orElse(components.collectFirst { - case Some(component: ICapabilityProvider) if component.hasCapability(capability, localFacing) => component.getCapability(capability, localFacing) - }).getOrElse(null.asInstanceOf[T]) + super.getCapability(capability, facing) } - override def writeToNBTForClient(nbt: NBTTagCompound) { + override def saveForClient(nbt: CompoundNBT) { connectComponents() - super.writeToNBTForClient(nbt) - save(nbt) + super.saveForClient(nbt) + saveData(nbt) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) - load(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) + loadData(nbt) connectComponents() } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala index c05425bf82..4baff36ce7 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala @@ -13,16 +13,16 @@ import li.cil.oc.integration.opencomputers.DriverRedstoneCard import li.cil.oc.server.agent import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagString -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.StringNBT +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable trait Computer extends Environment with ComponentInventory with Rotatable with BundledRedstoneAware with api.network.Analyzable with api.machine.MachineHost with StateAware with Tickable { @@ -54,18 +54,18 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B if (value) { hasErrored = false } - if (getWorld != null) { - getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) - if (getWorld.isRemote) { + if (getLevel != null) { + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) + if (getLevel.isClientSide) { runSound.foreach(sound => - if (_isRunning) Sound.startLoop(this, sound, 0.5f, 50 + getWorld.rand.nextInt(50)) + if (_isRunning) Sound.startLoop(this, sound, 0.5f, 50 + getLevel.random.nextInt(50)) else Sound.stopLoop(this) ) } } } - @SideOnly(Side.CLIENT) + @OnlyIn(Dist.CLIENT) def setUsers(list: Iterable[String]) { _users.clear() _users ++= list @@ -78,8 +78,8 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B // ----------------------------------------------------------------------- // - override def internalComponents(): lang.Iterable[ItemStack] = (0 until getSizeInventory).collect { - case slot if !getStackInSlot(slot).isEmpty && isComponentSlot(slot, getStackInSlot(slot)) => getStackInSlot(slot) + override def internalComponents(): lang.Iterable[ItemStack] = (0 until getContainerSize).collect { + case slot if !getItem(slot).isEmpty && isComponentSlot(slot, getItem(slot)) => getItem(slot) } @@ -122,7 +122,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B } protected def onRunningChanged(): Unit = { - markDirty() + setChanged() ServerPacketSender.sendComputerState(this) } @@ -140,62 +140,62 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B private final val IsRunningTag = Settings.namespace + "isRunning" private final val UsersTag = Settings.namespace + "users" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) // God, this is so ugly... will need to rework the robot architecture. // This is required for loading auxiliary data (kernel state), because the // coordinates in the actual robot won't be set properly, otherwise. this match { - case proxy: RobotProxy => proxy.robot.setPos(getPos) + case proxy: RobotProxy => proxy.robot.setLevelAndPosition(getLevel, getBlockPos) case _ => } - machine.load(nbt.getCompoundTag(ComputerTag)) + machine.loadData(nbt.getCompound(ComputerTag)) // Kickstart initialization to avoid values getting overwritten by - // readFromNBTForClient if that packet is handled after a manual + // loadForClient if that packet is handled after a manual // initialization / state change packet. setRunning(machine.isRunning) _isOutputEnabled = hasRedstoneCard } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) if (machine != null) { - nbt.setNewCompoundTag(ComputerTag, machine.save) + nbt.setNewCompoundTag(ComputerTag, machine.saveData) } } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) hasErrored = nbt.getBoolean(HasErroredTag) setRunning(nbt.getBoolean(IsRunningTag)) _users.clear() - _users ++= nbt.getTagList(UsersTag, NBT.TAG_STRING).map((tag: NBTTagString) => tag.getString) - if (_isRunning) runSound.foreach(sound => Sound.startLoop(this, sound, 0.5f, 1000 + getWorld.rand.nextInt(2000))) + _users ++= nbt.getList(UsersTag, NBT.TAG_STRING).map((tag: StringNBT) => tag.getAsString) + if (_isRunning) runSound.foreach(sound => Sound.startLoop(this, sound, 0.5f, 1000 + getLevel.random.nextInt(2000))) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setBoolean(HasErroredTag, machine != null && machine.lastError != null) - nbt.setBoolean(IsRunningTag, isRunning) - nbt.setNewTagList(UsersTag, machine.users.map(user => new NBTTagString(user))) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putBoolean(HasErroredTag, machine != null && machine.lastError != null) + nbt.putBoolean(IsRunningTag, isRunning) + nbt.setNewTagList(UsersTag, machine.users.map(user => StringNBT.valueOf(user))) } // ----------------------------------------------------------------------- // - override def markDirty() { - super.markDirty() + override def setChanged() { + super.setChanged() if (isServer) { machine.onHostChanged() setOutputEnabled(hasRedstoneCard) } } - override def isUsableByPlayer(player: EntityPlayer): Boolean = - super.isUsableByPlayer(player) && (player match { + override def stillValid(player: PlayerEntity): Boolean = + super.stillValid(player) && (player match { case fakePlayer: agent.Player => canInteract(fakePlayer.agent.ownerName()) - case _ => canInteract(player.getName) + case _ => canInteract(player.getName.getString) }) override protected def onRotationChanged() { @@ -211,5 +211,5 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B // ----------------------------------------------------------------------- // - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala index ce5c928a73..9f71cb00e2 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Environment.scala @@ -6,13 +6,15 @@ import li.cil.oc.api.network.Connector import li.cil.oc.api.network.SidedEnvironment import li.cil.oc.common.EventHandler import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraftforge.client.model.data.IModelData +import net.minecraftforge.client.model.data.ModelProperty -trait Environment extends TileEntity with network.Environment with network.EnvironmentHost { +trait Environment extends TileEntity with network.Environment with network.EnvironmentHost with IModelData { protected var isChangeScheduled = false - override def world = getWorld + override def world = getLevel override def xPosition = x + 0.5 @@ -20,7 +22,7 @@ trait Environment extends TileEntity with network.Environment with network.Envir override def zPosition = z + 0.5 - override def markChanged() = if (this.isInstanceOf[Tickable]) isChangeScheduled = true else getWorld.markChunkDirty(getPos, this) + override def markChanged() = if (this.isInstanceOf[Tickable]) isChangeScheduled = true else getLevel.blockEntityChanged(getBlockPos, this) protected def isConnected = node != null && node.address != null && node.network != null @@ -36,7 +38,7 @@ trait Environment extends TileEntity with network.Environment with network.Envir override def updateEntity() { super.updateEntity() if (isChangeScheduled) { - getWorld.markChunkDirty(getPos, this) + getLevel.blockEntityChanged(getBlockPos, this) isChangeScheduled = false } } @@ -46,7 +48,7 @@ trait Environment extends TileEntity with network.Environment with network.Envir if (isServer) { Option(node).foreach(_.remove) this match { - case sidedEnvironment: SidedEnvironment => for (side <- EnumFacing.values) { + case sidedEnvironment: SidedEnvironment => for (side <- Direction.values) { Option(sidedEnvironment.sidedNode(side)).foreach(_.remove()) } case _ => @@ -58,17 +60,17 @@ trait Environment extends TileEntity with network.Environment with network.Envir private final val NodeTag = Settings.namespace + "node" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) if (node != null && node.host == this) { - node.load(nbt.getCompoundTag(NodeTag)) + node.loadData(nbt.getCompound(NodeTag)) } } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) if (node != null && node.host == this) { - nbt.setNewCompoundTag(NodeTag, node.save) + nbt.setNewCompoundTag(NodeTag, node.saveData) } } @@ -95,4 +97,18 @@ trait Environment extends TileEntity with network.Environment with network.Envir // ----------------------------------------------------------------------- // protected def result(args: Any*) = li.cil.oc.util.ResultWrapper.result(args: _*) + + // ----------------------------------------------------------------------- // + + @Deprecated + override def getModelData() = this + + @Deprecated + override def hasProperty(prop: ModelProperty[_]) = false + + @Deprecated + override def getData[T](prop: ModelProperty[T]): T = null.asInstanceOf[T] + + @Deprecated + override def setData[T](prop: ModelProperty[T], value: T): T = null.asInstanceOf[T] } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala index 82ef43ca12..d21fb66f19 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Hub.scala @@ -6,11 +6,11 @@ import li.cil.oc.api.network._ import li.cil.oc.common.tileentity.traits import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.MovingAverage -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import scala.collection.mutable @@ -23,9 +23,9 @@ trait Hub extends traits.Environment with SidedEnvironment with Tickable { plug.node.address != null && plug.node.network != null) - protected val plugs = EnumFacing.values.map(side => createPlug(side)) + protected val plugs = Direction.values.map(side => createPlug(side)) - val queue = mutable.Queue.empty[(Option[EnumFacing], Packet)] + val queue = mutable.Queue.empty[(Option[Direction], Packet)] var maxQueueSize = queueBaseSize @@ -54,10 +54,10 @@ trait Hub extends traits.Environment with SidedEnvironment with Tickable { // ----------------------------------------------------------------------- // - @SideOnly(Side.CLIENT) - override def canConnect(side: EnumFacing) = side != null + @OnlyIn(Dist.CLIENT) + override def canConnect(side: Direction) = side != null - override def sidedNode(side: EnumFacing) = if (side != null) plugs(side.ordinal).node else null + override def sidedNode(side: Direction) = if (side != null) plugs(side.ordinal).node else null // ----------------------------------------------------------------------- // @@ -79,13 +79,13 @@ trait Hub extends traits.Environment with SidedEnvironment with Tickable { relayCooldown = relayDelay - 1 } } - else if (getWorld.getTotalWorldTime % relayDelay == 0) { + else if (getLevel.getGameTime % relayDelay == 0) { packetsPerCycleAvg += 0 } } } - def tryEnqueuePacket(sourceSide: Option[EnumFacing], packet: Packet) = queue.synchronized { + def tryEnqueuePacket(sourceSide: Option[Direction], packet: Packet) = queue.synchronized { if (packet.ttl > 0 && queue.size < maxQueueSize) { queue += sourceSide -> packet.hop() if (relayCooldown < 0) { @@ -96,8 +96,8 @@ trait Hub extends traits.Environment with SidedEnvironment with Tickable { else false } - protected def relayPacket(sourceSide: Option[EnumFacing], packet: Packet) { - for (side <- EnumFacing.values) { + protected def relayPacket(sourceSide: Option[Direction], packet: Packet) { + for (side <- Direction.values) { if (sourceSide.isEmpty || sourceSide.get != side) { val node = sidedNode(side) if (node != null) { @@ -114,51 +114,51 @@ trait Hub extends traits.Environment with SidedEnvironment with Tickable { private final val SideTag = "side" private final val RelayCooldownTag = Settings.namespace + "relayCooldown" - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - nbt.getTagList(PlugsTag, NBT.TAG_COMPOUND).toArray[NBTTagCompound]. + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + nbt.getList(PlugsTag, NBT.TAG_COMPOUND).toTagArray[CompoundNBT]. zipWithIndex.foreach { - case (tag, index) => plugs(index).node.load(tag) + case (tag, index) => plugs(index).node.loadData(tag) } - nbt.getTagList(QueueTag, NBT.TAG_COMPOUND).foreach( - (tag: NBTTagCompound) => { + nbt.getList(QueueTag, NBT.TAG_COMPOUND).foreach( + (tag: CompoundNBT) => { val side = tag.getDirection(SideTag) val packet = api.Network.newPacket(tag) queue += side -> packet }) - if (nbt.hasKey(RelayCooldownTag)) { - relayCooldown = nbt.getInteger(RelayCooldownTag) + if (nbt.contains(RelayCooldownTag)) { + relayCooldown = nbt.getInt(RelayCooldownTag) } } - override def writeToNBTForServer(nbt: NBTTagCompound) = queue.synchronized { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) = queue.synchronized { + super.saveForServer(nbt) // Side check for Waila (and other mods that may call this client side). if (isServer) { nbt.setNewTagList(PlugsTag, plugs.map(plug => { - val plugNbt = new NBTTagCompound() + val plugNbt = new CompoundNBT() if (plug.node != null) - plug.node.save(plugNbt) + plug.node.saveData(plugNbt) plugNbt })) nbt.setNewTagList(QueueTag, queue.map { case (sourceSide, packet) => - val tag = new NBTTagCompound() + val tag = new CompoundNBT() tag.setDirection(SideTag, sourceSide) - packet.save(tag) + packet.saveData(tag) tag }) if (relayCooldown > 0) { - nbt.setInteger(RelayCooldownTag, relayCooldown) + nbt.putInt(RelayCooldownTag, relayCooldown) } } } // ----------------------------------------------------------------------- // - protected def createPlug(side: EnumFacing) = new Plug(side) + protected def createPlug(side: Direction) = new Plug(side) - protected class Plug(val side: EnumFacing) extends api.network.Environment { + protected class Plug(val side: Direction) extends api.network.Environment { val node = createNode(this) override def onMessage(message: Message) { diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Inventory.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Inventory.scala index 38ae6cad4e..f08db57d6a 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Inventory.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Inventory.scala @@ -1,16 +1,18 @@ package li.cil.oc.common.tileentity.traits +import java.util.function.Consumer + import li.cil.oc.common.inventory import li.cil.oc.util.BlockPosition import li.cil.oc.util.InventoryUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction import net.minecraft.util.text.ITextComponent trait Inventory extends TileEntity with inventory.Inventory { - private lazy val inventory = Array.fill[ItemStack](getSizeInventory)(ItemStack.EMPTY) + private lazy val inventory = Array.fill[ItemStack](getContainerSize)(ItemStack.EMPTY) def items = inventory @@ -18,29 +20,31 @@ trait Inventory extends TileEntity with inventory.Inventory { override def getDisplayName: ITextComponent = super[Inventory].getDisplayName - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - load(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + loadData(nbt) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - save(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + saveData(nbt) } // ----------------------------------------------------------------------- // - override def isUsableByPlayer(player: EntityPlayer) = - player.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= 64 + override def stillValid(player: PlayerEntity) = + player.distanceToSqr(x + 0.5, y + 0.5, z + 0.5) <= 64 // ----------------------------------------------------------------------- // - def dropSlot(slot: Int, count: Int = getInventoryStackLimit, direction: Option[EnumFacing] = None) = - InventoryUtils.dropSlot(BlockPosition(x, y, z, getWorld), this, slot, count, direction) + def forAllLoot(dst: Consumer[ItemStack]): Unit = InventoryUtils.forAllSlots(this, dst) + + def dropSlot(slot: Int, count: Int = getMaxStackSize, direction: Option[Direction] = None) = + InventoryUtils.dropSlot(BlockPosition(x, y, z, getLevel), this, slot, count, direction) def dropAllSlots() = - InventoryUtils.dropAllSlots(BlockPosition(x, y, z, getWorld), this) + InventoryUtils.dropAllSlots(BlockPosition(x, y, z, getLevel), this) - def spawnStackInWorld(stack: ItemStack, direction: Option[EnumFacing] = None) = - InventoryUtils.spawnStackInWorld(BlockPosition(x, y, z, getWorld), stack, direction) + def spawnStackInWorld(stack: ItemStack, direction: Option[Direction] = None) = + InventoryUtils.spawnStackInWorld(BlockPosition(x, y, z, getLevel), stack, direction) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/NotAnalyzable.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/NotAnalyzable.scala index ab04a1141a..45f1692a61 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/NotAnalyzable.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/NotAnalyzable.scala @@ -2,9 +2,9 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network.Node -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.util.EnumFacing +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.util.Direction trait NotAnalyzable extends Analyzable { - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = null + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = null } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/OpenSides.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/OpenSides.scala index cc8f3bb63d..389776ac81 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/OpenSides.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/OpenSides.scala @@ -1,50 +1,51 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.Settings -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import li.cil.oc.util.RotationHelper +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn /** * @author Vexatos */ trait OpenSides extends TileEntity { - protected def SideCount = EnumFacing.VALUES.length + protected def SideCount = RotationHelper.getNumDirections protected def defaultState: Boolean = false var openSides = Array.fill(SideCount)(defaultState) - def compressSides = (EnumFacing.values(), openSides).zipped.foldLeft(0)((acc, entry) => acc | (if (entry._2) 1 << entry._1.ordinal() else 0)).toByte + def compressSides = (Direction.values(), openSides).zipped.foldLeft(0)((acc, entry) => acc | (if (entry._2) 1 << entry._1.ordinal() else 0)).toByte - def uncompressSides(byte: Byte) = EnumFacing.values().map(d => ((1 << d.ordinal()) & byte) != 0) + def uncompressSides(byte: Byte) = Direction.values().map(d => ((1 << d.ordinal()) & byte) != 0) - def isSideOpen(side: EnumFacing) = side != null && openSides(side.ordinal()) + def isSideOpen(side: Direction) = side != null && openSides(side.ordinal()) - def setSideOpen(side: EnumFacing, value: Boolean): Unit = if (side != null && openSides(side.ordinal()) != value) { + def setSideOpen(side: Direction, value: Boolean): Unit = if (side != null && openSides(side.ordinal()) != value) { openSides(side.ordinal()) = value } - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - if (nbt.hasKey(Settings.namespace + "openSides")) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) + if (nbt.contains(Settings.namespace + "openSides")) openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides")) } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setByte(Settings.namespace + "openSides", compressSides) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) + nbt.putByte(Settings.namespace + "openSides", compressSides) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides")) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setByte(Settings.namespace + "openSides", compressSides) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putByte(Settings.namespace + "openSides", compressSides) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/PlayerInputAware.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/PlayerInputAware.scala index 7701b48b0f..885a92b3c9 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/PlayerInputAware.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/PlayerInputAware.scala @@ -1,14 +1,14 @@ package li.cil.oc.common.tileentity.traits -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack // Used to get notifications from containers when a player changes a slot in -// this inventory. Normally the player causing a setInventorySlotContents is +// this inventory. Normally the player causing a setItem is // unavailable. Using this we gain access to the causing player, allowing for // some player-specific logic, such as the disassembler working instantaneously // when used by a player in creative mode. trait PlayerInputAware extends IInventory { - def onSetInventorySlotContents(player: EntityPlayer, slot: Int, stack: ItemStack): Unit + def onSetInventorySlotContents(player: PlayerEntity, slot: Int, stack: ItemStack): Unit } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/PowerAcceptor.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/PowerAcceptor.scala index cfdade18dd..dc91b37ad8 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/PowerAcceptor.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/PowerAcceptor.scala @@ -2,5 +2,4 @@ package li.cil.oc.common.tileentity.traits trait PowerAcceptor extends power.Common - with power.IndustrialCraft2Experimental - with power.AppliedEnergistics2 + // with power.AppliedEnergistics2 diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/PowerBalancer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/PowerBalancer.scala index f66269a245..b533f6a1a4 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/PowerBalancer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/PowerBalancer.scala @@ -3,7 +3,7 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.Settings import li.cil.oc.api.network.Connector import li.cil.oc.api.network.SidedEnvironment -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction trait PowerBalancer extends PowerInformation with SidedEnvironment with Tickable { var globalBuffer, globalBufferSize = 0.0 @@ -12,7 +12,7 @@ trait PowerBalancer extends PowerInformation with SidedEnvironment with Tickable override def updateEntity() { super.updateEntity() - if (isServer && isConnected && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (isServer && isConnected && getLevel.getGameTime % Settings.get.tickFrequency == 0) { val nodes = connectors def network(connector: Connector) = if (connector != null && connector.network != null) connector.network else this // Yeeeeah, so that just happened... it's not a beauty, but it works. This @@ -55,7 +55,7 @@ trait PowerBalancer extends PowerInformation with SidedEnvironment with Tickable (sumBuffer, sumSize) } - private def connectors = EnumFacing.values.view.map(sidedNode(_) match { + private def connectors = Direction.values.view.map(sidedNode(_) match { case connector: Connector => connector case _ => null }) diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/PowerInformation.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/PowerInformation.scala index 43dff2cf3c..0bf77a62b4 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/PowerInformation.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/PowerInformation.scala @@ -2,9 +2,9 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.Settings import li.cil.oc.server.{PacketSender => ServerPacketSender} -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.nbt.CompoundNBT +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn trait PowerInformation extends TileEntity { private var lastSentRatio = -1.0 @@ -43,17 +43,17 @@ trait PowerInformation extends TileEntity { private final val GlobalBufferTag = Settings.namespace + "globalBuffer" private final val GlobalBufferSizeTag = Settings.namespace + "globalBufferSize" - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) globalBuffer = nbt.getDouble(GlobalBufferTag) globalBufferSize = nbt.getDouble(GlobalBufferSizeTag) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) lastSentRatio = if (globalBufferSize > 0) globalBuffer / globalBufferSize else 0 - nbt.setDouble(GlobalBufferTag, globalBuffer) - nbt.setDouble(GlobalBufferSizeTag, globalBufferSize) + nbt.putDouble(GlobalBufferTag, globalBuffer) + nbt.putDouble(GlobalBufferSizeTag, globalBufferSize) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala index c2a3563220..d2a35706b0 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala @@ -5,12 +5,12 @@ import li.cil.oc.Settings import li.cil.oc.common.EventHandler import li.cil.oc.integration.util.BundledRedstone import li.cil.oc.server.{PacketSender => ServerPacketSender} -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn -case class RedstoneChangedEventArgs (side: EnumFacing, oldValue: Int, newValue: Int, color: Int = -1) +case class RedstoneChangedEventArgs (side: Direction, oldValue: Int, newValue: Int, color: Int = -1) trait RedstoneAware extends RotationAware { protected[tileentity] val _input: Array[Int] = Array.fill(6)(-1) @@ -59,9 +59,9 @@ trait RedstoneAware extends RotationAware { def getInput: Array[Int] = _input.map(math.max(_, 0)) - def getInput(side: EnumFacing): Int = _input(side.ordinal) max 0 + def getInput(side: Direction): Int = _input(side.ordinal) max 0 - def setInput(side: EnumFacing, newInput: Int): Unit = { + def setInput(side: Direction, newInput: Int): Unit = { val oldInput = _input(side.ordinal()) _input(side.ordinal()) = newInput if (oldInput >= 0 && newInput != oldInput) { @@ -70,7 +70,7 @@ trait RedstoneAware extends RotationAware { } def setInput(values: Array[Int]): Unit = { - for (side <- EnumFacing.values) { + for (side <- Direction.values) { val value = if (side.ordinal <= values.length) values(side.ordinal) else 0 setInput(side, value) } @@ -78,13 +78,13 @@ trait RedstoneAware extends RotationAware { def maxInput: Int = _input.map(math.max(_, 0)).max - def getOutput: Array[Int] = EnumFacing.values.map{ side: EnumFacing => _output(toLocal(side).ordinal) } + def getOutput: Array[Int] = Direction.values.map{ side: Direction => _output(toLocal(side).ordinal) } - def getOutput(side: EnumFacing) = if (_output != null && _output.length > toLocal(side).ordinal()) + def getOutput(side: Direction) = if (_output != null && _output.length > toLocal(side).ordinal()) _output(toLocal(side).ordinal()) else 0 - def setOutput(side: EnumFacing, value: Int): Boolean = { + def setOutput(side: Direction, value: Int): Boolean = { if (value == getOutput(side)) return false _output(toLocal(side).ordinal()) = value onRedstoneOutputChanged(side) @@ -93,7 +93,7 @@ trait RedstoneAware extends RotationAware { def setOutput(values: util.Map[_, _]): Boolean = { var changed: Boolean = false - EnumFacing.values.foreach(side => { + Direction.values.foreach(side => { val sideIndex = toLocal(side).ordinal // due to a bug in our jnlua layer, I cannot loop the map valueToInt(getObjectFuzzy(values, sideIndex)) match { @@ -108,7 +108,7 @@ trait RedstoneAware extends RotationAware { if (this.isInstanceOf[Tickable]) { shouldUpdateInput = isServer } else { - EnumFacing.values().foreach(updateRedstoneInput) + Direction.values().foreach(updateRedstoneInput) } } @@ -119,24 +119,24 @@ trait RedstoneAware extends RotationAware { if (isServer) { if (shouldUpdateInput) { shouldUpdateInput = false - EnumFacing.values().foreach(updateRedstoneInput) + Direction.values().foreach(updateRedstoneInput) } } } - override def validate(): Unit = { - super.validate() + override def clearRemoved(): Unit = { + super.clearRemoved() if (!this.isInstanceOf[Tickable]) { - EventHandler.scheduleServer(() => EnumFacing.values().foreach(updateRedstoneInput)) + EventHandler.scheduleServer(() => Direction.values().foreach(updateRedstoneInput)) } } - def updateRedstoneInput(side: EnumFacing): Unit = setInput(side, BundledRedstone.computeInput(position, side)) + def updateRedstoneInput(side: Direction): Unit = setInput(side, BundledRedstone.computeInput(position, side)) // ----------------------------------------------------------------------- // - override def readFromNBTForServer(nbt: NBTTagCompound): Unit = { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT): Unit = { + super.loadForServer(nbt) val input = nbt.getIntArray(Settings.namespace + "rs.input") input.copyToArray(_input, 0, input.length min _input.length) @@ -144,24 +144,24 @@ trait RedstoneAware extends RotationAware { output.copyToArray(_output, 0, output.length min _output.length) } - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT): Unit = { + super.saveForServer(nbt) - nbt.setIntArray(Settings.namespace + "rs.input", _input) - nbt.setIntArray(Settings.namespace + "rs.output", _output) + nbt.putIntArray(Settings.namespace + "rs.input", _input) + nbt.putIntArray(Settings.namespace + "rs.output", _output) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) _isOutputEnabled = nbt.getBoolean("isOutputEnabled") nbt.getIntArray("output").copyToArray(_output) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setBoolean("isOutputEnabled", _isOutputEnabled) - nbt.setIntArray("output", _output) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putBoolean("isOutputEnabled", _isOutputEnabled) + nbt.putIntArray("output", _output) } // ----------------------------------------------------------------------- // @@ -169,19 +169,19 @@ trait RedstoneAware extends RotationAware { protected def onRedstoneInputChanged(args: RedstoneChangedEventArgs) {} protected def onRedstoneOutputEnabledChanged() { - if (getWorld != null) { - getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, true) + if (getLevel != null) { + getLevel.updateNeighborsAt(getBlockPos, getBlockState.getBlock) if (isServer) ServerPacketSender.sendRedstoneState(this) - else getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + else getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) } } - protected def onRedstoneOutputChanged(side: EnumFacing) { - val blockPos = getPos.offset(side) - getWorld.neighborChanged(blockPos, getBlockType, blockPos) - getWorld.notifyNeighborsOfStateExcept(blockPos, getWorld.getBlockState(blockPos).getBlock, side.getOpposite) + protected def onRedstoneOutputChanged(side: Direction) { + val blockPos = getBlockPos.relative(side) + getLevel.neighborChanged(blockPos, getBlockState.getBlock, blockPos) + getLevel.updateNeighborsAtExceptFromFacing(blockPos, getLevel.getBlockState(blockPos).getBlock, side.getOpposite) if (isServer) ServerPacketSender.sendRedstoneState(this) - else getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + else getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Rotatable.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Rotatable.scala index 9a223605d9..fab750e853 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Rotatable.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Rotatable.scala @@ -1,14 +1,16 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.api.internal +import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.block.property.PropertyRotatable import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedEnumFacing._ import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.RotationHelper -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.entity.Entity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.Rotation /** TileEntity base class for rotatable blocks. */ trait Rotatable extends RotationAware with internal.Rotatable { @@ -16,92 +18,98 @@ trait Rotatable extends RotationAware with internal.Rotatable { // Lookup tables // ----------------------------------------------------------------------- // - private val pitch2Direction = Array(EnumFacing.UP, EnumFacing.NORTH, EnumFacing.DOWN) + private val pitch2Direction = Array(Direction.UP, Direction.NORTH, Direction.DOWN) - private val yaw2Direction = Array(EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.NORTH, EnumFacing.EAST) + private val yaw2Direction = Array(Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.EAST) // ----------------------------------------------------------------------- // // Accessors // ----------------------------------------------------------------------- // - def pitch = if (getWorld != null && getWorld.isBlockLoaded(getPos)) getBlockType match { - case rotatable if getWorld.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Pitch) => getWorld.getBlockState(getPos).getValue(PropertyRotatable.Pitch) - case _ => EnumFacing.NORTH + def pitch = if (getLevel != null && getLevel.isLoaded(getBlockPos)) getBlockState.getBlock match { + case rotatable if getLevel.getBlockState(getBlockPos).getProperties.contains(PropertyRotatable.Pitch) => getLevel.getBlockState(getBlockPos).getValue(PropertyRotatable.Pitch) + case _ => Direction.NORTH } else null - def pitch_=(value: EnumFacing): Unit = + def pitch_=(value: Direction): Unit = trySetPitchYaw(value match { - case EnumFacing.DOWN | EnumFacing.UP => value - case _ => EnumFacing.NORTH + case Direction.DOWN | Direction.UP => value + case _ => Direction.NORTH }, yaw) - def yaw = if (getWorld != null && getWorld.isBlockLoaded(getPos)) getBlockType match { - case rotatable if getWorld.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Yaw) => getWorld.getBlockState(getPos).getValue(PropertyRotatable.Yaw) - case rotatable if getWorld.getBlockState(getPos).getProperties.containsKey(PropertyRotatable.Facing) => getWorld.getBlockState(getPos).getValue(PropertyRotatable.Facing) - case _ => EnumFacing.SOUTH + def yaw = if (getLevel != null && getLevel.isLoaded(getBlockPos)) getBlockState.getBlock match { + case rotatable if getLevel.getBlockState(getBlockPos).getProperties.contains(PropertyRotatable.Yaw) => getLevel.getBlockState(getBlockPos).getValue(PropertyRotatable.Yaw) + case rotatable if getLevel.getBlockState(getBlockPos).getProperties.contains(PropertyRotatable.Facing) => getLevel.getBlockState(getBlockPos).getValue(PropertyRotatable.Facing) + case _ => Direction.SOUTH } else null - def yaw_=(value: EnumFacing): Unit = + def yaw_=(value: Direction): Unit = trySetPitchYaw(pitch, value match { - case EnumFacing.DOWN | EnumFacing.UP => yaw + case Direction.DOWN | Direction.UP => yaw case _ => value }) def setFromEntityPitchAndYaw(entity: Entity) = trySetPitchYaw( - pitch2Direction((entity.rotationPitch / 90).round + 1), - yaw2Direction((entity.rotationYaw / 360 * 4).round & 3)) + pitch2Direction((entity.xRot / 90).round + 1), + yaw2Direction((entity.yRot / 360 * 4).round & 3)) - def setFromFacing(value: EnumFacing) = + def setFromFacing(value: Direction) = value match { - case EnumFacing.DOWN | EnumFacing.UP => + case Direction.DOWN | Direction.UP => trySetPitchYaw(value, yaw) case yaw => - trySetPitchYaw(EnumFacing.NORTH, yaw) + trySetPitchYaw(Direction.NORTH, yaw) } def invertRotation() = trySetPitchYaw(pitch match { - case EnumFacing.DOWN | EnumFacing.UP => pitch.getOpposite - case _ => EnumFacing.NORTH + case Direction.DOWN | Direction.UP => pitch.getOpposite + case _ => Direction.NORTH }, yaw.getOpposite) override def facing = pitch match { - case EnumFacing.DOWN | EnumFacing.UP => pitch + case Direction.DOWN | Direction.UP => pitch case _ => yaw } - def rotate(axis: EnumFacing) = { - val block = getWorld.getBlock(position) - if (block != null) { - val valid = block.getValidRotations(getWorld, getPos) - if (valid != null && valid.contains(axis)) { - val (newPitch, newYaw) = facing.getRotation(axis) match { - case value@(EnumFacing.UP | EnumFacing.DOWN) => - if (value == pitch) (value, yaw.getRotation(axis)) - else (value, yaw) - case value => (EnumFacing.NORTH, value) + def rotate(axis: Direction) = { + val state = getLevel.getBlockState(getBlockPos) + state.getBlock match { + case simple: SimpleBlock => { + val valid = simple.getValidRotations(getLevel, getBlockPos) + if (valid != null && valid.contains(axis)) { + val (newPitch, newYaw) = facing.getRotation(axis) match { + case value@(Direction.UP | Direction.DOWN) => + if (value == pitch) (value, yaw.getRotation(axis)) + else (value, yaw) + case value => (Direction.NORTH, value) + } + trySetPitchYaw(newPitch, newYaw) } - trySetPitchYaw(newPitch, newYaw) + else false } - else false + case _ if axis == Direction.UP || axis == Direction.DOWN => { + val updated = state.rotate(getLevel, getBlockPos, if (axis == Direction.DOWN) Rotation.COUNTERCLOCKWISE_90 else Rotation.CLOCKWISE_90) + updated != state && getLevel.setBlockAndUpdate(getBlockPos, updated) + } + case _ => false } - else false } - override def toLocal(value: EnumFacing) = if (value == null) null else { + override def toLocal(value: Direction) = if (value == null) null else { val p = pitch val y = yaw if (p != null && y != null) RotationHelper.toLocal(pitch, yaw, value) else null } - override def toGlobal(value: EnumFacing) = if (value == null) null else { + override def toGlobal(value: Direction) = if (value == null) null else { val p = pitch val y = yaw if (p != null && y != null) RotationHelper.toGlobal(pitch, yaw, value) else null } - def validFacings = Array(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.EAST) + def validFacings = Array(Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST) // ----------------------------------------------------------------------- // @@ -110,36 +118,36 @@ trait Rotatable extends RotationAware with internal.Rotatable { ServerPacketSender.sendRotatableState(this) } else { - getWorld.notifyBlockUpdate(getPos) + getLevel.notifyBlockUpdate(getBlockPos) } - getWorld.notifyNeighborsOfStateChange(getPos, getBlockType, false) + getLevel.updateNeighborsAt(getBlockPos, getBlockState.getBlock) } // ----------------------------------------------------------------------- // /** Updates cached translation array and sends notification to clients. */ protected def updateTranslation(): Unit = { - if (getWorld != null) { + if (getLevel != null) { onRotationChanged() } } /** Validates new values against the allowed rotations as set in our block. */ - protected def trySetPitchYaw(pitch: EnumFacing, yaw: EnumFacing) = { - val oldState = getWorld.getBlockState(getPos) - def setState(newState: IBlockState): Boolean = { + protected def trySetPitchYaw(pitch: Direction, yaw: Direction) = { + val oldState = getLevel.getBlockState(getBlockPos) + def setState(newState: BlockState): Boolean = { if (oldState.hashCode() != newState.hashCode()) { - getWorld.setBlockState(getPos, newState) + getLevel.setBlockAndUpdate(getBlockPos, newState) updateTranslation() true } else false } - getBlockType match { - case rotatable if oldState.getProperties.containsKey(PropertyRotatable.Pitch) && oldState.getProperties.containsKey(PropertyRotatable.Yaw) => - setState(oldState.withProperty(PropertyRotatable.Pitch, pitch).withProperty(PropertyRotatable.Yaw, yaw)) - case rotatable if oldState.getProperties.containsKey(PropertyRotatable.Facing) => - setState(oldState.withProperty(PropertyRotatable.Facing, yaw)) + getBlockState.getBlock match { + case rotatable if oldState.hasProperty(PropertyRotatable.Pitch) && oldState.hasProperty(PropertyRotatable.Yaw) => + setState(oldState.setValue(PropertyRotatable.Pitch, pitch).setValue(PropertyRotatable.Yaw, yaw)) + case rotatable if oldState.hasProperty(PropertyRotatable.Facing) => + setState(oldState.setValue(PropertyRotatable.Facing, yaw)) case _ => false } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/RotatableTile.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/RotatableTile.scala index 0ea62e3c16..c7979fa09e 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/RotatableTile.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/RotatableTile.scala @@ -1,10 +1,11 @@ package li.cil.oc.common.tileentity.traits import li.cil.oc.Settings -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import li.cil.oc.util.RotationHelper +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn /** * Like Rotatable, but stores the rotation information in the TE's NBT instead @@ -16,10 +17,10 @@ trait RotatableTile extends Rotatable { // ----------------------------------------------------------------------- // /** One of Up, Down and North (where north means forward/no pitch). */ - private var _pitch = EnumFacing.NORTH + private var _pitch = Direction.NORTH /** One of the four cardinal directions. */ - private var _yaw = EnumFacing.SOUTH + private var _yaw = Direction.SOUTH // ----------------------------------------------------------------------- // // Accessors @@ -34,43 +35,43 @@ trait RotatableTile extends Rotatable { private final val PitchTag = Settings.namespace + "pitch" private final val YawTag = Settings.namespace + "yaw" - override def readFromNBTForServer(nbt: NBTTagCompound) = { - super.readFromNBTForServer(nbt) - if (nbt.hasKey(PitchTag)) { - pitch = EnumFacing.getFront(nbt.getInteger(PitchTag)) + override def loadForServer(nbt: CompoundNBT) = { + super.loadForServer(nbt) + if (nbt.contains(PitchTag)) { + pitch = Direction.from3DDataValue(nbt.getInt(PitchTag)) } - if (nbt.hasKey(YawTag)) { - yaw = EnumFacing.getFront(nbt.getInteger(YawTag)) + if (nbt.contains(YawTag)) { + yaw = Direction.from3DDataValue(nbt.getInt(YawTag)) } validatePitchAndYaw() } - override def writeToNBTForServer(nbt: NBTTagCompound) = { - super.writeToNBTForServer(nbt) - nbt.setInteger(PitchTag, pitch.ordinal) - nbt.setInteger(YawTag, yaw.ordinal) + override def saveForServer(nbt: CompoundNBT) = { + super.saveForServer(nbt) + nbt.putInt(PitchTag, pitch.ordinal) + nbt.putInt(YawTag, yaw.ordinal) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) - pitch = EnumFacing.getFront(nbt.getInteger(PitchTag)) - yaw = EnumFacing.getFront(nbt.getInteger(YawTag)) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) + pitch = Direction.from3DDataValue(nbt.getInt(PitchTag)) + yaw = Direction.from3DDataValue(nbt.getInt(YawTag)) validatePitchAndYaw() } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - nbt.setInteger(PitchTag, pitch.ordinal) - nbt.setInteger(YawTag, yaw.ordinal) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + nbt.putInt(PitchTag, pitch.ordinal) + nbt.putInt(YawTag, yaw.ordinal) } private def validatePitchAndYaw() { if (!_pitch.getAxis.isVertical) { - _pitch = EnumFacing.NORTH + _pitch = Direction.NORTH } if (!_yaw.getAxis.isHorizontal) { - _yaw = EnumFacing.SOUTH + _yaw = Direction.SOUTH } updateTranslation() } @@ -78,7 +79,7 @@ trait RotatableTile extends Rotatable { // ----------------------------------------------------------------------- // /** Validates new values against the allowed rotations as set in our block. */ - override protected def trySetPitchYaw(pitch: EnumFacing, yaw: EnumFacing) = { + override protected def trySetPitchYaw(pitch: Direction, yaw: Direction) = { var changed = false if (pitch != _pitch) { changed = true diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/RotationAware.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/RotationAware.scala index 908f8d52d8..8c134796ab 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/RotationAware.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/RotationAware.scala @@ -1,9 +1,9 @@ package li.cil.oc.common.tileentity.traits -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction trait RotationAware extends TileEntity { - def toLocal(value: EnumFacing) = value + def toLocal(value: Direction) = value - def toGlobal(value: EnumFacing) = value + def toGlobal(value: Direction) = value } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala index bc0ae7798f..59212aba8f 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/TextBuffer.scala @@ -5,9 +5,9 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.internal import li.cil.oc.api.network.Node -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.nbt.CompoundNBT +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn trait TextBuffer extends Environment with Tickable { lazy val buffer: internal.TextBuffer = { @@ -32,24 +32,24 @@ trait TextBuffer extends Environment with Tickable { // ----------------------------------------------------------------------- // - override def readFromNBTForServer(nbt: NBTTagCompound): Unit = { - super.readFromNBTForServer(nbt) - buffer.load(nbt) + override def loadForServer(nbt: CompoundNBT): Unit = { + super.loadForServer(nbt) + buffer.loadData(nbt) } - override def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - super.writeToNBTForServer(nbt) - buffer.save(nbt) + override def saveForServer(nbt: CompoundNBT): Unit = { + super.saveForServer(nbt) + buffer.saveData(nbt) } - @SideOnly(Side.CLIENT) - override def readFromNBTForClient(nbt: NBTTagCompound) { - super.readFromNBTForClient(nbt) - buffer.load(nbt) + @OnlyIn(Dist.CLIENT) + override def loadForClient(nbt: CompoundNBT) { + super.loadForClient(nbt) + buffer.loadData(nbt) } - override def writeToNBTForClient(nbt: NBTTagCompound) { - super.writeToNBTForClient(nbt) - buffer.save(nbt) + override def saveForClient(nbt: CompoundNBT) { + super.saveForClient(nbt) + buffer.saveData(nbt) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Tickable.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Tickable.scala index 9632cb67e9..b7e65db5b4 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Tickable.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Tickable.scala @@ -1,7 +1,7 @@ package li.cil.oc.common.tileentity.traits -import net.minecraft.util.ITickable +import net.minecraft.tileentity.ITickableTileEntity -trait Tickable extends TileEntity with ITickable { - override def update(): Unit = updateEntity() +trait Tickable extends TileEntity with ITickableTileEntity { + override def tick(): Unit = updateEntity() } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala index 4607894d4d..a4e96ff011 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala @@ -6,50 +6,50 @@ import li.cil.oc.client.Sound import li.cil.oc.common.SaveHandler import li.cil.oc.util.BlockPosition import li.cil.oc.util.SideTracker -import net.minecraft.block.state.IBlockState -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.block.BlockState +import net.minecraft.nbt.CompoundNBT import net.minecraft.network.NetworkManager -import net.minecraft.network.play.server.SPacketUpdateTileEntity +import net.minecraft.network.play.server.SUpdateTileEntityPacket import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn trait TileEntity extends net.minecraft.tileentity.TileEntity { private final val IsServerDataTag = Settings.namespace + "isServerData" - def x: Int = getPos.getX + def x: Int = getBlockPos.getX - def y: Int = getPos.getY + def y: Int = getBlockPos.getY - def z: Int = getPos.getZ + def z: Int = getBlockPos.getZ - def position = BlockPosition(x, y, z, getWorld) + def position = BlockPosition(x, y, z, getLevel) def isClient: Boolean = !isServer - def isServer: Boolean = if (getWorld != null) !getWorld.isRemote else SideTracker.isServer + def isServer: Boolean = if (getLevel != null) !getLevel.isClientSide else SideTracker.isServer // ----------------------------------------------------------------------- // def updateEntity() { - if (Settings.get.periodicallyForceLightUpdate && getWorld.getTotalWorldTime % 40 == 0 && getBlockType.getLightValue(getWorld.getBlockState(getPos), getWorld, getPos) > 0) { - getWorld.notifyBlockUpdate(getPos, getWorld.getBlockState(getPos), getWorld.getBlockState(getPos), 3) + if (Settings.get.periodicallyForceLightUpdate && getLevel.getGameTime % 40 == 0 && getBlockState.getBlock.getLightValue(getLevel.getBlockState(getBlockPos), getLevel, getBlockPos) > 0) { + getLevel.sendBlockUpdated(getBlockPos, getLevel.getBlockState(getBlockPos), getLevel.getBlockState(getBlockPos), 3) } } - override def validate() { - super.validate() + override def clearRemoved() { + super.clearRemoved() initialize() } - override def invalidate() { - super.invalidate() + override def setRemoved() { + super.setRemoved() dispose() } - override def onChunkUnload() { - super.onChunkUnload() + override def onChunkUnloaded() { + super.onChunkUnloaded() try dispose() catch { case t: Throwable => OpenComputers.log.error("Failed properly disposing a tile entity, things may leak and or break.", t) } @@ -67,53 +67,52 @@ trait TileEntity extends net.minecraft.tileentity.TileEntity { // ----------------------------------------------------------------------- // - override def shouldRefresh(world: World, pos: BlockPos, oldState: IBlockState, newSate: IBlockState): Boolean = oldState.getBlock != newSate.getBlock + def loadForServer(nbt: CompoundNBT) {} - def readFromNBTForServer(nbt: NBTTagCompound): Unit = super.readFromNBT(nbt) - - def writeToNBTForServer(nbt: NBTTagCompound): Unit = { - nbt.setBoolean(IsServerDataTag, true) - super.writeToNBT(nbt) + def saveForServer(nbt: CompoundNBT): Unit = { + nbt.putBoolean(IsServerDataTag, true) + super.save(nbt) } - @SideOnly(Side.CLIENT) - def readFromNBTForClient(nbt: NBTTagCompound) {} + @OnlyIn(Dist.CLIENT) + def loadForClient(nbt: CompoundNBT) {} - def writeToNBTForClient(nbt: NBTTagCompound): Unit = { - nbt.setBoolean(IsServerDataTag, false) + def saveForClient(nbt: CompoundNBT): Unit = { + nbt.putBoolean(IsServerDataTag, false) } // ----------------------------------------------------------------------- // - override def readFromNBT(nbt: NBTTagCompound): Unit = { + override def load(state: BlockState, nbt: CompoundNBT): Unit = { + super.load(state, nbt) if (isServer || nbt.getBoolean(IsServerDataTag)) { - readFromNBTForServer(nbt) + loadForServer(nbt) } else { - readFromNBTForClient(nbt) + loadForClient(nbt) } } - override def writeToNBT(nbt: NBTTagCompound): NBTTagCompound = { + override def save(nbt: CompoundNBT): CompoundNBT = { if (isServer) { - writeToNBTForServer(nbt) + saveForServer(nbt) } nbt } - override def getUpdatePacket: SPacketUpdateTileEntity = { + override def getUpdatePacket: SUpdateTileEntityPacket = { // Obfuscation workaround. If it works. val te = this.asInstanceOf[net.minecraft.tileentity.TileEntity] - new SPacketUpdateTileEntity(te.getPos, te.getBlockMetadata, te.getUpdateTag) + new SUpdateTileEntityPacket(te.getBlockPos, 0, te.getUpdateTag) } - override def getUpdateTag: NBTTagCompound = { + override def getUpdateTag: CompoundNBT = { val nbt = super.getUpdateTag // See comment on savingForClients variable. SaveHandler.savingForClients = true try { - try writeToNBTForClient(nbt) catch { + try saveForClient(nbt) catch { case e: Throwable => OpenComputers.log.warn("There was a problem writing a TileEntity description packet. Please report this if you see it!", e) } } finally { @@ -123,8 +122,8 @@ trait TileEntity extends net.minecraft.tileentity.TileEntity { nbt } - override def onDataPacket(manager: NetworkManager, packet: SPacketUpdateTileEntity) { - try readFromNBTForClient(packet.getNbtCompound) catch { + override def onDataPacket(manager: NetworkManager, packet: SUpdateTileEntityPacket) { + try loadForClient(packet.getTag) catch { case e: Throwable => OpenComputers.log.warn("There was a problem reading a TileEntity description packet. Please report this if you see it!", e) } } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/AppliedEnergistics2.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/AppliedEnergistics2.scala index 9d31151b8a..5e78937a19 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/AppliedEnergistics2.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/power/AppliedEnergistics2.scala @@ -1,7 +1,7 @@ package li.cil.oc.common.tileentity.traits.power import java.util -import appeng.api.AEApi +import appeng.api._ import appeng.api.config.Actionable import appeng.api.config.PowerMultiplier import appeng.api.networking._ @@ -10,14 +10,16 @@ import appeng.api.util.{AECableType, AEColor, AEPartLocation, DimensionalCoord} import li.cil.oc.Settings import li.cil.oc.common.EventHandler import li.cil.oc.integration.Mods +import li.cil.oc.integration.appeng.AEUtil import li.cil.oc.integration.util.Power import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraft.util.math.BlockPos import net.minecraft.world.World import net.minecraftforge.fml.common._ -import scala.collection.JavaConversions +import scala.collection.JavaConverters trait AppliedEnergistics2 extends Common with IGridHost { private lazy val useAppliedEnergistics2Power = isServer && Mods.AppliedEnergistics2.isModAvailable @@ -27,12 +29,11 @@ trait AppliedEnergistics2 extends Common with IGridHost { override def updateEntity() { super.updateEntity() - if (useAppliedEnergistics2Power && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (useAppliedEnergistics2Power && getLevel.getGameTime % Settings.get.tickFrequency == 0) { updateEnergy() } } - @Optional.Method(modid = Mods.IDs.AppliedEnergistics2) private def updateEnergy() { tryAllSides((demand, _) => { val grid = getGridNode(AEPartLocation.INTERNAL).getGrid @@ -47,37 +48,36 @@ trait AppliedEnergistics2 extends Common with IGridHost { }, Power.fromAE, Power.toAE) } - override def validate() { - super.validate() - if (useAppliedEnergistics2Power) EventHandler.scheduleAE2Add(this) + override def clearRemoved() { + super.clearRemoved() + if (useAppliedEnergistics2Power) EventHandler.AE2.scheduleAE2Add(this) } - override def invalidate() { - super.invalidate() + override def setRemoved() { + super.setRemoved() if (useAppliedEnergistics2Power) securityBreak() } - override def onChunkUnload() { - super.onChunkUnload() + override def onChunkUnloaded() { + super.onChunkUnloaded() if (useAppliedEnergistics2Power) securityBreak() } // ----------------------------------------------------------------------- // - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) + override def loadForServer(nbt: CompoundNBT) { + super.loadForServer(nbt) if (useAppliedEnergistics2Power) loadNode(nbt) } - @Optional.Method(modid = Mods.IDs.AppliedEnergistics2) - private def loadNode(nbt: NBTTagCompound): Unit = { + private def loadNode(nbt: CompoundNBT): Unit = { getGridNode(AEPartLocation.INTERNAL).loadFromNBT(Settings.namespace + "ae2power", nbt) } - override def setWorld(worldIn: World): Unit = { - if (getWorld == worldIn) + override def setLevelAndPosition(worldIn: World, pos: BlockPos): Unit = { + if (getLevel == worldIn) return - super.setWorld(worldIn) + super.setLevelAndPosition(worldIn, pos) if (worldIn != null && isServer && useAppliedEnergistics2Power) { val gridNode = getGridNode(AEPartLocation.INTERNAL) if (gridNode != null) { @@ -86,32 +86,28 @@ trait AppliedEnergistics2 extends Common with IGridHost { } } - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) + override def saveForServer(nbt: CompoundNBT) { + super.saveForServer(nbt) if (useAppliedEnergistics2Power) saveNode(nbt) } - @Optional.Method(modid = Mods.IDs.AppliedEnergistics2) - private def saveNode(nbt: NBTTagCompound): Unit = { + private def saveNode(nbt: CompoundNBT): Unit = { getGridNode(AEPartLocation.INTERNAL).saveToNBT(Settings.namespace + "ae2power", nbt) } // ----------------------------------------------------------------------- // - @Optional.Method(modid = Mods.IDs.AppliedEnergistics2) def getGridNode(side: AEPartLocation): IGridNode = node match { case Some(gridNode: IGridNode) => gridNode case _ if isServer => - val gridNode = AEApi.instance.grid.createGridNode(new AppliedEnergistics2GridBlock(this)) + val gridNode = AEUtil.aeApi.get.grid.createGridNode(new AppliedEnergistics2GridBlock(this)) node = Option(gridNode) gridNode case _ => null } - @Optional.Method(modid = Mods.IDs.AppliedEnergistics2) def getCableConnectionType(side: AEPartLocation): AECableType = AECableType.SMART - @Optional.Method(modid = Mods.IDs.AppliedEnergistics2) def securityBreak() { getGridNode(AEPartLocation.INTERNAL).destroy() } @@ -130,12 +126,10 @@ class AppliedEnergistics2GridBlock(val tileEntity: AppliedEnergistics2) extends override def onGridNotification(p1: GridNotification): Unit = {} - override def setNetworkStatus(p1: IGrid, p2: Int): Unit = {} - - override def getConnectableSides: util.EnumSet[EnumFacing] = { - val connectableSides = JavaConversions.asJavaCollection(EnumFacing.values.filter(tileEntity.canConnectPower)) + override def getConnectableSides: util.EnumSet[Direction] = { + val connectableSides = JavaConverters.asJavaCollection(Direction.values.filter(tileEntity.canConnectPower)) if (connectableSides.isEmpty) { - val s = util.EnumSet.copyOf(JavaConversions.asJavaCollection(EnumFacing.values)) + val s = util.EnumSet.copyOf(JavaConverters.asJavaCollection(Direction.values)) s.clear() s } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Common.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/Common.scala index fc240c9d95..c25351b9b9 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Common.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/power/Common.scala @@ -3,25 +3,25 @@ package li.cil.oc.common.tileentity.traits.power import li.cil.oc.Settings import li.cil.oc.api.network.Connector import li.cil.oc.common.tileentity.traits.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraft.util.Direction +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn trait Common extends TileEntity { - @SideOnly(Side.CLIENT) - protected def hasConnector(side: EnumFacing) = false + @OnlyIn(Dist.CLIENT) + protected def hasConnector(side: Direction) = false - protected def connector(side: EnumFacing): Option[Connector] = None + protected def connector(side: Direction): Option[Connector] = None // ----------------------------------------------------------------------- // def energyThroughput: Double - protected def tryAllSides(provider: (Double, EnumFacing) => Double, fromOther: Double => Double, toOther: Double => Double) { + protected def tryAllSides(provider: (Double, Direction) => Double, fromOther: Double => Double, toOther: Double => Double) { // We make sure to only call this every `Settings.get.tickFrequency` ticks, // but our throughput is per tick, so multiply this up for actual budget. var budget = energyThroughput * Settings.get.tickFrequency - for (side <- EnumFacing.values) { + for (side <- Direction.values) { val demand = toOther(math.min(budget, globalDemand(side))) if (demand > 1) { val energy = fromOther(provider(demand, side)) @@ -34,7 +34,7 @@ trait Common extends TileEntity { // ----------------------------------------------------------------------- // - def canConnectPower(side: EnumFacing) = + def canConnectPower(side: Direction) = !Settings.get.ignorePower && (if (isClient) hasConnector(side) else connector(side).isDefined) /** @@ -45,7 +45,7 @@ trait Common extends TileEntity { * @param doReceive whether to actually inject energy or only simulate it. * @return the amount of energy that was actually injected. */ - def tryChangeBuffer(side: EnumFacing, amount: Double, doReceive: Boolean = true): Double = + def tryChangeBuffer(side: Direction, amount: Double, doReceive: Boolean = true): Double = if (isClient || Settings.get.ignorePower) 0 else connector(side) match { case Some(node) => @@ -55,19 +55,19 @@ trait Common extends TileEntity { case _ => 0 } - def globalBuffer(side: EnumFacing): Double = + def globalBuffer(side: Direction): Double = if (isClient) 0 else connector(side) match { case Some(node) => node.globalBuffer case _ => 0 } - def globalBufferSize(side: EnumFacing): Double = + def globalBufferSize(side: Direction): Double = if (isClient) 0 else connector(side) match { case Some(node) => node.globalBufferSize case _ => 0 } - def globalDemand(side: EnumFacing) = math.max(0, math.min(energyThroughput, globalBufferSize(side) - globalBuffer(side))) + def globalDemand(side: Direction) = math.max(0, math.min(energyThroughput, globalBufferSize(side) - globalBuffer(side))) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Factorization.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/Factorization.scala deleted file mode 100644 index 2d2371c4f1..0000000000 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Factorization.scala +++ /dev/null @@ -1,95 +0,0 @@ -package li.cil.oc.common.tileentity.traits.power -/* TODO Factorization - -import cpw.mods.fml.common.Optional -import factorization.api.Charge -import factorization.api.Coord -import factorization.api.IChargeConductor -import li.cil.oc.OpenComputers -import li.cil.oc.Settings -import li.cil.oc.common.asm.Injectable -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.Power -import net.minecraft.nbt.NBTTagCompound - -@Injectable.Interface(value = "factorization.api.IChargeConductor", modid = Mods.IDs.Factorization) -trait Factorization extends Common { - private lazy val useFactorizationPower = isServer && Mods.Factorization.isAvailable - - @Optional.Method(modid = Mods.IDs.Factorization) - private lazy val charge: AnyRef = this match { - case conductor: IChargeConductor => new Charge(conductor) - case _ => - OpenComputers.log.warn("Failed setting up Factorization power, which most likely means the class transformer did not run. You're probably running in an incorrectly configured development environment. Try adding `-Dfml.coreMods.load=li.cil.oc.common.launch.TransformerLoader` to the VM options of your run configuration.") - null - } - - // ----------------------------------------------------------------------- // - - override def updateEntity() { - if (useFactorizationPower) updateEnergy() - super.updateEntity() - } - - @Optional.Method(modid = Mods.IDs.Factorization) - private def updateEnergy() { - getCharge.update() - if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) { - tryAllSides((demand, _) => getCharge.deplete(demand.toInt), Power.fromCharge, Power.toCharge) - } - } - - override def invalidate() { - if (useFactorizationPower) invalidateCharge() - super.invalidate() - } - - @Optional.Method(modid = Mods.IDs.Factorization) - private def invalidateCharge() { - getCharge.invalidate() - } - - override def onChunkUnload() { - if (useFactorizationPower) removeCharge() - super.onChunkUnload() - } - - @Optional.Method(modid = Mods.IDs.Factorization) - private def removeCharge() { - if (!isInvalid) getCharge.remove() - } - - // ----------------------------------------------------------------------- // - - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - if (useFactorizationPower) loadCharge(nbt) - } - - @Optional.Method(modid = Mods.IDs.Factorization) - private def loadCharge(nbt: NBTTagCompound) { - getCharge.readFromNBT(nbt, "fzpower") - } - - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - if (useFactorizationPower) saveCharge(nbt) - } - - @Optional.Method(modid = Mods.IDs.Factorization) - private def saveCharge(nbt: NBTTagCompound) { - getCharge.writeToNBT(nbt, "fzpower") - } - - // ----------------------------------------------------------------------- // - - @Optional.Method(modid = Mods.IDs.Factorization) - def getCharge = if (Mods.Factorization.isAvailable) charge.asInstanceOf[Charge] else null - - @Optional.Method(modid = Mods.IDs.Factorization) - def getInfo = "" - - @Optional.Method(modid = Mods.IDs.Factorization) - def getCoord = new Coord(this) -} -*/ \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Galacticraft.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/Galacticraft.scala deleted file mode 100644 index 449c1be224..0000000000 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Galacticraft.scala +++ /dev/null @@ -1,44 +0,0 @@ -package li.cil.oc.common.tileentity.traits.power -/* TODO Galacticraft - -import cpw.mods.fml.common.Optional -import li.cil.oc.common.asm.Injectable -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.Power -import micdoodle8.mods.galacticraft.api.power.EnergySource -import micdoodle8.mods.galacticraft.api.transmission.NetworkType -import net.minecraftforge.common.util.ForgeDirection - -import scala.language.implicitConversions - -@Injectable.InterfaceList(Array( - new Injectable.Interface(value = "micdoodle8.mods.galacticraft.api.power.IEnergyHandlerGC", modid = Mods.IDs.Galacticraft), - new Injectable.Interface(value = "micdoodle8.mods.galacticraft.api.transmission.tile.IConnector", modid = Mods.IDs.Galacticraft) -)) -trait Galacticraft extends Common { - private implicit def toDirection(source: EnergySource): ForgeDirection = source match { - case adjacent: EnergySource.EnergySourceAdjacent => adjacent.direction - case _ => ForgeDirection.UNKNOWN - } - - @Optional.Method(modid = Mods.IDs.Galacticraft) - def nodeAvailable(from: EnergySource) = Mods.Galacticraft.isAvailable && canConnectPower(from) - - @Optional.Method(modid = Mods.IDs.Galacticraft) - def receiveEnergyGC(from: EnergySource, amount: Float, simulate: Boolean) = - if (!Mods.Galacticraft.isAvailable) 0f - else Power.toGC(tryChangeBuffer(from, Power.fromGC(amount), !simulate)) - - @Optional.Method(modid = Mods.IDs.Galacticraft) - def getEnergyStoredGC(from: EnergySource) = Power.toGC(globalBuffer(from)) - - @Optional.Method(modid = Mods.IDs.Galacticraft) - def getMaxEnergyStoredGC(from: EnergySource) = Power.toGC(globalBufferSize(from)) - - @Optional.Method(modid = Mods.IDs.Galacticraft) - def extractEnergyGC(from: EnergySource, amount: Float, simulate: Boolean) = 0f - - @Optional.Method(modid = Mods.IDs.Galacticraft) - def canConnect(from: ForgeDirection, networkType: NetworkType): Boolean = networkType == NetworkType.POWER && canConnectPower(from) -} -*/ \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Classic.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Classic.scala deleted file mode 100644 index 52d32871ac..0000000000 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Classic.scala +++ /dev/null @@ -1,101 +0,0 @@ -package li.cil.oc.common.tileentity.traits.power -/* TODO IC2 Classic - -import cpw.mods.fml.common.Optional -import cpw.mods.fml.common.eventhandler.Event -import ic2classic.api.Direction -import li.cil.oc.OpenComputers -import li.cil.oc.Settings -import li.cil.oc.common.EventHandler -import li.cil.oc.common.asm.Injectable -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.Power -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.tileentity.TileEntity -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.common.util.ForgeDirection - -@Injectable.Interface(value = "ic2classic.api.energy.tile.IEnergySink", modid = Mods.IDs.IndustrialCraft2Classic) -trait IndustrialCraft2Classic extends Common with IndustrialCraft2Common { - private var conversionBuffer = 0.0 - - private lazy val useIndustrialCraft2ClassicPower = isServer && Mods.IndustrialCraft2Classic.isAvailable - - // ----------------------------------------------------------------------- // - - override def updateEntity() { - super.updateEntity() - if (useIndustrialCraft2ClassicPower && world.getTotalWorldTime % Settings.get.tickFrequency == 0) { - updateEnergy() - } - } - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) - private def updateEnergy() { - tryAllSides((demand, _) => { - val result = math.min(demand, conversionBuffer) - conversionBuffer -= result - result - }, Power.fromEU, Power.toEU) - } - - override def validate() { - super.validate() - if (useIndustrialCraft2ClassicPower && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this) - } - - override def invalidate() { - super.invalidate() - if (useIndustrialCraft2ClassicPower && addedToIC2PowerGrid) removeFromIC2Grid() - } - - override def onChunkUnload() { - super.onChunkUnload() - if (useIndustrialCraft2ClassicPower && addedToIC2PowerGrid) removeFromIC2Grid() - } - - private def removeFromIC2Grid() { - try MinecraftForge.EVENT_BUS.post(Class.forName("ic2classic.api.energy.event.EnergyTileUnloadEvent").getConstructor(Class.forName("ic2classic.api.energy.tile.IEnergyTile")).newInstance(this).asInstanceOf[Event]) catch { - case t: Throwable => OpenComputers.log.warn("Error removing node from IC2 grid.", t) - } - addedToIC2PowerGrid = false - } - - // ----------------------------------------------------------------------- // - - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - conversionBuffer = nbt.getDouble(Settings.namespace + "ic2cpower") - } - - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setDouble(Settings.namespace + "ic2cpower", conversionBuffer) - } - - // ----------------------------------------------------------------------- // - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) - def isAddedToEnergyNet: Boolean = addedToIC2PowerGrid - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) - def getMaxSafeInput: Int = Int.MaxValue - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) - def acceptsEnergyFrom(emitter: TileEntity, direction: Direction) = useIndustrialCraft2ClassicPower && canConnectPower(direction.toForgeDirection) - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) - def injectEnergy(directionFrom: Direction, amount: Int): Boolean = { - conversionBuffer += amount - true - } - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2Classic) - def demandsEnergy: Int = { - if (!useIndustrialCraft2ClassicPower) 0 - else if (conversionBuffer < energyThroughput * Settings.get.tickFrequency) - math.min(ForgeDirection.VALID_DIRECTIONS.map(globalDemand).max, Power.toEU(energyThroughput)).toInt - else 0 - } -} -*/ \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Common.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Common.scala deleted file mode 100644 index 368b2ff19b..0000000000 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Common.scala +++ /dev/null @@ -1,5 +0,0 @@ -package li.cil.oc.common.tileentity.traits.power - -trait IndustrialCraft2Common { - var addedToIC2PowerGrid = false -} diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Experimental.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Experimental.scala deleted file mode 100644 index b1b7eecea8..0000000000 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Experimental.scala +++ /dev/null @@ -1,96 +0,0 @@ -package li.cil.oc.common.tileentity.traits.power - -import ic2.api.energy.tile.IEnergyEmitter -import li.cil.oc.OpenComputers -import li.cil.oc.Settings -import li.cil.oc.common.EventHandler -import li.cil.oc.common.asm.Injectable -import li.cil.oc.common.tileentity.traits -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.Power -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.fml.common.Optional -import net.minecraftforge.fml.common.eventhandler.Event - -@Injectable.Interface(value = "ic2.api.energy.tile.IEnergySink", modid = Mods.IDs.IndustrialCraft2) -trait IndustrialCraft2Experimental extends Common with IndustrialCraft2Common with traits.Tickable { - private var conversionBuffer = 0.0 - - private lazy val useIndustrialCraft2Power = isServer && Mods.IndustrialCraft2.isModAvailable - - // ----------------------------------------------------------------------- // - - override def updateEntity() { - super.updateEntity() - if (useIndustrialCraft2Power && getWorld.getTotalWorldTime % Settings.get.tickFrequency == 0) { - updateEnergy() - } - } - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2) - private def updateEnergy() { - tryAllSides((demand, _) => { - val result = math.min(demand, conversionBuffer) - conversionBuffer -= result - result - }, Power.fromEU, Power.toEU) - } - - override def validate() { - super.validate() - if (useIndustrialCraft2Power && !addedToIC2PowerGrid) EventHandler.scheduleIC2Add(this) - } - - override def invalidate() { - super.invalidate() - if (useIndustrialCraft2Power && addedToIC2PowerGrid) removeFromIC2Grid() - } - - override def onChunkUnload() { - super.onChunkUnload() - if (useIndustrialCraft2Power && addedToIC2PowerGrid) removeFromIC2Grid() - } - - private def removeFromIC2Grid() { - try MinecraftForge.EVENT_BUS.post(Class.forName("ic2.api.energy.event.EnergyTileUnloadEvent").getConstructor(Class.forName("ic2.api.energy.tile.IEnergyTile")).newInstance(this).asInstanceOf[Event]) catch { - case t: Throwable => OpenComputers.log.warn("Error removing node from IC2 grid.", t) - } - addedToIC2PowerGrid = false - } - - // ----------------------------------------------------------------------- // - - override def readFromNBTForServer(nbt: NBTTagCompound) { - super.readFromNBTForServer(nbt) - conversionBuffer = nbt.getDouble(Settings.namespace + "ic2power") - } - - override def writeToNBTForServer(nbt: NBTTagCompound) { - super.writeToNBTForServer(nbt) - nbt.setDouble(Settings.namespace + "ic2power", conversionBuffer) - } - - // ----------------------------------------------------------------------- // - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2) - def getSinkTier: Int = Int.MaxValue - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2) - def acceptsEnergyFrom(emitter: IEnergyEmitter, direction: EnumFacing): Boolean = useIndustrialCraft2Power && canConnectPower(direction) - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2) - def injectEnergy(directionFrom: EnumFacing, amount: Double, voltage: Double): Double = { - conversionBuffer += amount - 0.0 - } - - @Optional.Method(modid = Mods.IDs.IndustrialCraft2) - def getDemandedEnergy: Double = { - if (!useIndustrialCraft2Power) 0.0 - else if (conversionBuffer < energyThroughput * Settings.get.tickFrequency) - math.min(EnumFacing.VALUES.map(globalDemand).max, Power.toEU(energyThroughput)) - else 0 - } -} diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Mekanism.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/Mekanism.scala deleted file mode 100644 index f41d755fe8..0000000000 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/Mekanism.scala +++ /dev/null @@ -1,29 +0,0 @@ -package li.cil.oc.common.tileentity.traits.power -/* TODO Mekanism - -import cpw.mods.fml.common.Optional -import li.cil.oc.common.asm.Injectable -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.Power -import net.minecraftforge.common.util.ForgeDirection - -@Injectable.Interface(value = "mekanism.api.energy.IStrictEnergyAcceptor", modid = Mods.IDs.Mekanism) -trait Mekanism extends Common { - @Optional.Method(modid = Mods.IDs.Mekanism) - def canReceiveEnergy(side: ForgeDirection) = Mods.Mekanism.isAvailable && canConnectPower(side) - - @Optional.Method(modid = Mods.IDs.Mekanism) - def transferEnergyToAcceptor(side: ForgeDirection, amount: Double) = - if (!Mods.Mekanism.isAvailable) 0 - else Power.toJoules(tryChangeBuffer(side, Power.fromJoules(amount))) - - @Optional.Method(modid = Mods.IDs.Mekanism) - def getMaxEnergy = Power.toJoules(ForgeDirection.VALID_DIRECTIONS.map(globalBufferSize).max) - - @Optional.Method(modid = Mods.IDs.Mekanism) - def getEnergy = Power.toJoules(ForgeDirection.VALID_DIRECTIONS.map(globalBuffer).max) - - @Optional.Method(modid = Mods.IDs.Mekanism) - def setEnergy(energy: Double) {} -} -*/ \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/power/RotaryCraft.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/power/RotaryCraft.scala deleted file mode 100644 index 576757427d..0000000000 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/power/RotaryCraft.scala +++ /dev/null @@ -1,90 +0,0 @@ -package li.cil.oc.common.tileentity.traits.power -/* TODO RotaryCraft -import li.cil.oc.OpenComputers -import li.cil.oc.Settings -import li.cil.oc.common.asm.Injectable -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.Power -import net.minecraft.util.EnumFacing -import net.minecraftforge.fml.common.Optional - -@Injectable.Interface(value = "Reika.RotaryCraft.API.Power.ShaftPowerReceiver", modid = Mods.IDs.RotaryCraft) -trait RotaryCraft extends Common { - private lazy val useRotaryCraftPower = isServer && Mods.RotaryCraft.isAvailable - - private var omega = 0 - private var torque = 0 - private var power = 0L - private var alpha = 0 - - // ----------------------------------------------------------------------- // - - override def updateEntity() { - if (useRotaryCraftPower) updateEnergy() - super.updateEntity() - } - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - private def updateEnergy() { - if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) { - tryAllSides((demand, _) => { - val consumed = demand.toLong min power - power -= consumed - consumed - }, Power.fromWA, Power.toWA) - } - } - - // ----------------------------------------------------------------------- // - // ShaftMachine - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def getOmega: Int = omega - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def getTorque: Int = torque - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def getPower: Long = power - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def getName: String = OpenComputers.Name - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def getIORenderAlpha: Int = alpha - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def setIORenderAlpha(value: Int): Unit = alpha = value - - // ----------------------------------------------------------------------- // - // ShaftPowerReceiver - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def setOmega(value: Int): Unit = omega = value - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def setTorque(value: Int): Unit = torque = value - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def setPower(value: Long): Unit = power = value - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def noInputMachine(): Unit = { - omega = 0 - torque = 0 - power = 0 - } - - // ----------------------------------------------------------------------- // - // PowerAcceptor - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def canReadFrom(forgeDirection: EnumFacing): Boolean = true - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def isReceiving: Boolean = true - - @Optional.Method(modid = Mods.IDs.RotaryCraft) - def getMinTorque(available: Int): Int = 0 -} -*/ \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/ModProxy.java b/src/main/scala/li/cil/oc/integration/ModProxy.java index a33ed4bdc5..fed1dbd932 100644 --- a/src/main/scala/li/cil/oc/integration/ModProxy.java +++ b/src/main/scala/li/cil/oc/integration/ModProxy.java @@ -3,5 +3,11 @@ public interface ModProxy { Mod getMod(); - void initialize(); + default void preInitialize() + { + } + + default void initialize() + { + } } diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index d961d8d763..1c5c330ed9 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -1,17 +1,20 @@ package li.cil.oc.integration +import java.util.Optional + import li.cil.oc.Settings import li.cil.oc.integration -import net.minecraftforge.fml.common.Loader -import net.minecraftforge.fml.common.ModAPIManager -import net.minecraftforge.fml.common.versioning.ArtifactVersion -import net.minecraftforge.fml.common.versioning.VersionParser +import net.minecraftforge.fml.ModList +import net.minecraftforge.fml.ModContainer +import net.minecraftforge.forgespi.language.MavenVersionAdapter +import org.apache.maven.artifact.versioning.ArtifactVersion import scala.collection.mutable import scala.collection.mutable.ArrayBuffer object Mods { - private val handlers = mutable.Set.empty[ModProxy] + private var preInited = false + private var inited = false private val knownMods = mutable.ArrayBuffer.empty[ModBase] @@ -20,57 +23,66 @@ object Mods { def All: ArrayBuffer[ModBase] = knownMods.clone() val AppliedEnergistics2 = new ClassBasedMod(IDs.AppliedEnergistics2, "appeng.api.storage.channels.IItemStorageChannel") val ComputerCraft = new SimpleMod(IDs.ComputerCraft) - val ExtraCells = new SimpleMod(IDs.ExtraCells, version = "@[2.5.2,)") - val Forestry = new SimpleMod(IDs.Forestry, version = "@[5.2,)") - val IndustrialCraft2 = new SimpleMod(IDs.IndustrialCraft2) val Forge = new SimpleMod(IDs.Forge) val JustEnoughItems = new SimpleMod(IDs.JustEnoughItems) val Mekanism = new SimpleMod(IDs.Mekanism) - val MekanismGas = new SimpleMod(IDs.MekanismGas) val Minecraft = new SimpleMod(IDs.Minecraft) val OpenComputers = new SimpleMod(IDs.OpenComputers) - val TIS3D = new SimpleMod(IDs.TIS3D, version = "@[0.9,)") - val Waila = new SimpleMod(IDs.Waila) - val ProjectRedBase = new SimpleMod((IDs.ProjectRedCore)) + val TIS3D = new SimpleMod(IDs.TIS3D, version = "[0.9,)") val ProjectRedTransmission = new SimpleMod((IDs.ProjectRedTransmission)) val DraconicEvolution = new SimpleMod(IDs.DraconicEvolution) val EnderStorage = new SimpleMod(IDs.EnderStorage) - val Thaumcraft = new SimpleMod(IDs.Thaumcraft) - val Charset = new SimpleMod(IDs.Charset) - val WirelessRedstoneCBE = new SimpleMod(IDs.WirelessRedstoneCBE) // ----------------------------------------------------------------------- // val Proxies = Array( integration.appeng.ModAppEng, - integration.ec.ModExtraCells, - integration.forestry.ModForestry, - integration.ic2.ModIndustrialCraft2, integration.minecraftforge.ModMinecraftForge, integration.tis3d.ModTIS3D, integration.mekanism.ModMekanism, - integration.mekanism.gas.ModMekanismGas, integration.minecraft.ModMinecraft, - integration.waila.ModWaila, integration.projectred.ModProjectRed, integration.computercraft.ModComputerCraft, integration.enderstorage.ModEnderStorage, - integration.thaumcraft.ModThaumcraft, - integration.charset.ModCharset, - integration.wrcbe.ModWRCBE, // We go late to ensure all other mod integration is done, e.g. to // allow properly checking if wireless redstone is present. integration.opencomputers.ModOpenComputers ) + def preInit(): Unit = { + if (!preInited) { + preInited = true + for (proxy <- Proxies) { + tryPreInit(proxy) + } + } + } + + private def tryPreInit(mod: ModProxy) { + val handlers = mutable.Set.empty[ModProxy] + val isBlacklisted = Settings.get.modBlacklist.contains(mod.getMod.id) + val alwaysEnabled = mod.getMod == null || mod.getMod == Mods.Minecraft + if (!isBlacklisted && (alwaysEnabled || mod.getMod.isModAvailable) && handlers.add(mod)) { + li.cil.oc.OpenComputers.log.debug(s"Pre-initializing mod integration for '${mod.getMod.id}'.") + try mod.preInitialize() catch { + case e: Throwable => + li.cil.oc.OpenComputers.log.warn(s"Error pre-initializing integration for '${mod.getMod.id}'", e) + } + } + } + def init(): Unit = { - for (proxy <- Proxies) { - tryInit(proxy) + if (!inited) { + inited = true + for (proxy <- Proxies) { + tryInit(proxy) + } } } private def tryInit(mod: ModProxy) { + val handlers = mutable.Set.empty[ModProxy] val isBlacklisted = Settings.get.modBlacklist.contains(mod.getMod.id) val alwaysEnabled = mod.getMod == null || mod.getMod == Mods.Minecraft if (!isBlacklisted && (alwaysEnabled || mod.getMod.isModAvailable) && handlers.add(mod)) { @@ -87,28 +99,22 @@ object Mods { object IDs { final val AppliedEnergistics2 = "appliedenergistics2" final val ComputerCraft = "computercraft" - final val ExtraCells = "extracells" - final val Forestry = "forestry" final val Forge = "forge" - final val IndustrialCraft2 = "ic2" final val JustEnoughItems = "jei" final val Mekanism = "mekanism" - final val MekanismGas = "MekanismAPI|gas" final val Minecraft = "minecraft" final val OpenComputers = "opencomputers" final val TIS3D = "tis3d" final val Waila = "waila" - final val ProjectRedCore = "projectred-core" final val ProjectRedTransmission = "projectred-transmission" final val DraconicEvolution = "draconicevolution" final val EnderStorage = "enderstorage" - final val Thaumcraft = "thaumcraft" - final val Charset = "charset" - final val WirelessRedstoneCBE = "wrcbe" } // ----------------------------------------------------------------------- // + private def optionToScala[T](opt: Optional[T]): Option[T] = if (opt.isPresent) Some(opt.get) else None + trait ModBase extends Mod { knownMods += this @@ -116,24 +122,22 @@ object Mods { def id: String - def container = Option(Loader.instance.getIndexedModList.get(id)) + def container: Option[ModContainer] = optionToScala(ModList.get.getModContainerById(id)) - def version: Option[ArtifactVersion] = container.map(_.getProcessedVersion) + def version: Option[ArtifactVersion] = container.map(_.getModInfo.getVersion) } class SimpleMod(val id: String, version: String = "") extends ModBase { - private lazy val isModAvailable_ = { - val version = VersionParser.parseVersionReference(id + this.version) - if (Loader.isModLoaded(version.getLabel)) - version.containsVersion(Loader.instance.getIndexedModList.get(version.getLabel).getProcessedVersion) - else ModAPIManager.INSTANCE.hasAPI(version.getLabel) + private lazy val isModAvailable_ = optionToScala(ModList.get.getModContainerById(id)) match { + case Some(container) => version.isEmpty || MavenVersionAdapter.createFromVersionSpec(version).containsVersion(container.getModInfo.getVersion) + case _ => false } def isModAvailable: Boolean = isModAvailable_ } class ClassBasedMod(val id: String, val classNames: String*) extends ModBase { - private lazy val isModAvailable_ = Loader.isModLoaded(id) && classNames.forall(className => try Class.forName(className) != null catch { + private lazy val isModAvailable_ = ModList.get.isLoaded(id) && classNames.forall(className => try Class.forName(className) != null catch { case _: Throwable => false }) diff --git a/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala b/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala index a912105dcf..9e4bea2e64 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala @@ -1,8 +1,9 @@ package li.cil.oc.integration.appeng +import java.util.Optional import javax.annotation.Nonnull -import appeng.api.AEApi +import appeng.api._ import appeng.api.networking.IGrid import appeng.api.networking.crafting.ICraftingGrid import appeng.api.networking.energy.IEnergyGrid @@ -12,57 +13,61 @@ import appeng.api.storage.data.{IAEFluidStack, IAEItemStack} import appeng.api.storage.IStorageHelper import li.cil.oc.integration.Mods import net.minecraft.item.ItemStack -import net.minecraftforge.fml.common.versioning.VersionRange -import net.minecraftforge.fml.common.Loader +import net.minecraftforge.fml.ModList +import net.minecraftforge.forgespi.language.MavenVersionAdapter +import org.apache.maven.artifact.versioning.VersionRange + +@AEAddon +class AEUtil extends IAEAddon { + override def onAPIAvailable(aeApi: IAppEngApi) = AEUtil.onAPIAvailable(aeApi) +} object AEUtil { - val versionsWithNewItemDefinitionAPI: VersionRange = VersionRange.createFromVersionSpec("[rv6-stable-5,)") + var aeApi: Option[IAppEngApi] = None - val itemStorageChannel: IItemStorageChannel = AEApi.instance.storage.getStorageChannel[IAEItemStack, IItemStorageChannel](classOf[IItemStorageChannel]) - val fluidStorageChannel: IFluidStorageChannel = AEApi.instance.storage.getStorageChannel[IAEFluidStack, IFluidStorageChannel](classOf[IFluidStorageChannel]) + private def optionToScala[T](opt: Optional[T]): Option[T] = if (opt.isPresent) Some(opt.get) else None + + private def onAPIAvailable(aeApi: IAppEngApi) { + AEUtil.aeApi = Some(aeApi) + itemStorageChannel = aeApi.storage.getStorageChannel[IAEItemStack, IItemStorageChannel](classOf[IItemStorageChannel]) + fluidStorageChannel = aeApi.storage.getStorageChannel[IAEFluidStack, IFluidStorageChannel](classOf[IFluidStorageChannel]) + } - def useNewItemDefinitionAPI: Boolean = versionsWithNewItemDefinitionAPI.containsVersion( - Loader.instance.getIndexedModList.get(Mods.AppliedEnergistics2.id).getProcessedVersion) + val versionsWithNewItemDefinitionAPI: VersionRange = MavenVersionAdapter.createFromVersionSpec("[rv6-stable-5,)") + + var itemStorageChannel: IItemStorageChannel = null + var fluidStorageChannel: IFluidStorageChannel = null + + def useNewItemDefinitionAPI: Boolean = optionToScala(ModList.get.getModContainerById(Mods.AppliedEnergistics2.id)). + filter(container => versionsWithNewItemDefinitionAPI.containsVersion(container.getModInfo.getVersion)).isDefined // ----------------------------------------------------------------------- // - def controllerClass: Class[_] = { - if (AEApi.instance != null) { - val maybe = AEApi.instance.definitions.blocks.controller.maybeEntity - if (maybe.isPresent) - maybe.get() - else - null: Class[_] - } - else null: Class[_] - } + def controllerClass: Class[_] = aeApi.flatMap(api => optionToScala(api.definitions.blocks.controller.maybeEntity)).orNull // ----------------------------------------------------------------------- // - def interfaceClass: Class[_] = - if (AEApi.instance != null) - AEApi.instance.definitions.blocks.iface.maybeEntity.get() - else null: Class[_] + def interfaceClass: Class[_] = aeApi.map(api => api.definitions.blocks.iface.maybeEntity.get).orNull // ----------------------------------------------------------------------- // - def isController(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.blocks.controller.isSameAs(stack) + def isController(stack: ItemStack): Boolean = stack != null && aeApi.filter(_.definitions.blocks.controller.isSameAs(stack)).isDefined // ----------------------------------------------------------------------- // - def isExportBus(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.parts.exportBus.isSameAs(stack) + def isExportBus(stack: ItemStack): Boolean = stack != null && aeApi.filter(_.definitions.parts.exportBus.isSameAs(stack)).isDefined // ----------------------------------------------------------------------- // - def isImportBus(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.parts.importBus.isSameAs(stack) + def isImportBus(stack: ItemStack): Boolean = stack != null && aeApi.filter(_.definitions.parts.importBus.isSameAs(stack)).isDefined // ----------------------------------------------------------------------- // - def isBlockInterface(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.blocks.iface.isSameAs(stack) + def isBlockInterface(stack: ItemStack): Boolean = stack != null && aeApi.filter(_.definitions.blocks.iface.isSameAs(stack)).isDefined // ----------------------------------------------------------------------- // - def isPartInterface(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.parts.iface.isSameAs(stack) + def isPartInterface(stack: ItemStack): Boolean = stack != null && aeApi.filter(_.definitions.parts.iface.isSameAs(stack)).isDefined // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/integration/appeng/ConverterCellInventory.java b/src/main/scala/li/cil/oc/integration/appeng/ConverterCellInventory.java index d3499f887e..c6abf036cb 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/ConverterCellInventory.java +++ b/src/main/scala/li/cil/oc/integration/appeng/ConverterCellInventory.java @@ -1,10 +1,8 @@ package li.cil.oc.integration.appeng; -import appeng.api.AEApi; import appeng.api.implementations.items.IStorageCell; -import appeng.api.storage.ICellInventory; -import appeng.api.storage.ICellInventoryHandler; -import appeng.api.storage.IMEInventoryHandler; +import appeng.api.storage.cells.ICellInventory; +import appeng.api.storage.cells.ICellInventoryHandler; import appeng.api.storage.channels.IItemStorageChannel; import li.cil.oc.api.driver.Converter; import net.minecraft.item.ItemStack; @@ -22,7 +20,7 @@ public void convert(final Object value, final Map output) { output.put("remainingItemTypes", cell.getRemainingItemTypes()); output.put("getTotalItemTypes", cell.getTotalItemTypes()); - output.put("getAvailableItems", cell.getAvailableItems(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createList())); + output.put("getAvailableItems", cell.getAvailableItems(AEUtil.aeApi().get().storage().getStorageChannel(IItemStorageChannel.class).createList())); output.put("totalBytes", cell.getTotalBytes()); output.put("freeBytes", cell.getFreeBytes()); @@ -32,11 +30,11 @@ public void convert(final Object value, final Map output) { //output.put("getPreformattedItems",cell.getConfigInventory()); output.put("fuzzyMode", cell.getFuzzyMode().toString()); - output.put("name", cell.getItemStack().getDisplayName()); + output.put("name", cell.getItemStack().getDisplayName().getString()); } else if (value instanceof ICellInventoryHandler) { - convert(((ICellInventoryHandler) value).getCellInv(), output); + convert(((ICellInventoryHandler) value).getCellInv(), output); } else if ((value instanceof ItemStack) && (((ItemStack)value).getItem() instanceof IStorageCell)) { - IMEInventoryHandler inventory = AEApi.instance().registries().cell().getCellInventory((ItemStack) value, null, AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class)); + ICellInventoryHandler inventory = AEUtil.aeApi().get().registries().cell().getCellInventory((ItemStack) value, null, AEUtil.aeApi().get().storage().getStorageChannel(IItemStorageChannel.class)); if (inventory != null) convert(((ICellInventoryHandler) inventory).getCellInv(), output); } diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala index 8ff06a7148..1902a55e1a 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala @@ -18,15 +18,15 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ResultWrapper._ import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverBlockInterface extends DriverSidedTileEntity { def getTileEntityClass: Class[_] = AEUtil.interfaceClass - def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntity with ISegmentedInventory with IActionHost with IGridHost]) + def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[TileEntity with ISegmentedInventory with IActionHost with IGridHost]) final class Environment(val tile: TileEntity with ISegmentedInventory with IActionHost with IGridHost) extends ManagedTileEntityEnvironment[TileEntity with ISegmentedInventory with IActionHost](tile, "me_interface") with NamedBlock with NetworkControl[TileEntity with ISegmentedInventory with IActionHost with IGridHost] { override def preferredName = "me_interface" diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala index 10a900d4ff..86673f8d7c 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala @@ -10,7 +10,7 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World @@ -21,8 +21,8 @@ object DriverController extends DriverSidedTileEntity { def getTileEntityClass = AEUtil.controllerClass - def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileController]) + def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[TileController]) final class Environment(val tile: TileController) extends ManagedTileEntityEnvironment[TileController](tile, "me_controller") with NamedBlock with NetworkControl[TileController] { override def preferredName = "me_controller" diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala index 5f2f03696d..b9bbcc4571 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala @@ -1,6 +1,5 @@ package li.cil.oc.integration.appeng -import appeng.api.AEApi import appeng.api.config.{Actionable, FuzzyMode, Settings, Upgrades} import appeng.api.implementations.IUpgradeableHost import appeng.api.implementations.tiles.ISegmentedInventory @@ -22,19 +21,19 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.ResultWrapper._ import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.world.World import net.minecraft.util.math.BlockPos import net.minecraftforge.items.IItemHandler object DriverExportBus extends driver.DriverBlock { - override def worksWith(world: World, pos: BlockPos, side: EnumFacing) = - world.getTileEntity(pos) match { - case container: IPartHost => EnumFacing.VALUES.map(container.getPart).filter(p => p != null).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isExportBus) + override def worksWith(world: World, pos: BlockPos, side: Direction) = + world.getBlockEntity(pos) match { + case container: IPartHost => Direction.values.map(container.getPart).filter(p => p != null).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isExportBus) case _ => false } - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing) = new Environment(world.getTileEntity(pos).asInstanceOf[IPartHost]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction) = new Environment(world.getBlockEntity(pos).asInstanceOf[IPartHost]) final class Environment(val host: IPartHost) extends ManagedTileEntityEnvironment[IPartHost](host, "me_exportbus") with NamedBlock with PartEnvironmentBase { override def preferredName = "me_exportbus" @@ -75,7 +74,7 @@ object DriverExportBus extends driver.DriverBlock { val part = host.getPart(side) if (part == null || !AEUtil.isExportBus(part.getItemStack(PartItemStack.PICK))) { - return result(Unit, "no export bus") + return result((), "no export bus") } val exportBus = part.asInstanceOf[ISegmentedInventory with IConfigurableObject with IUpgradeableHost with IActionHost with IGridHost] @@ -83,7 +82,7 @@ object DriverExportBus extends driver.DriverBlock { val inventory: IItemHandler = InventoryUtils.inventoryAt(new BlockPosition(location.x, location.y, location.z, Some(location.getWorld)).offset(side), side.getOpposite) match { case Some(inv) => inv - case _ => return result(Unit, "no inventory") + case _ => return result((), "no inventory") } val targetSlot: Option[Int] = args.optSlot(inventory, 1, -1) match { @@ -121,7 +120,7 @@ object DriverExportBus extends driver.DriverBlock { } } if (potentialWork == count) - result(Unit, "no items moved") + result((), "no items moved") else result(potentialWork - count) } diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala index b18d15387f..ff57e10b24 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala @@ -10,18 +10,18 @@ import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.integration.ManagedTileEntityEnvironment import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverImportBus extends driver.DriverBlock { - override def worksWith(world: World, pos: BlockPos, side: EnumFacing) = - world.getTileEntity(pos) match { - case container: IPartHost => EnumFacing.VALUES.map(container.getPart).filter(p => p != null).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isImportBus) + override def worksWith(world: World, pos: BlockPos, side: Direction) = + world.getBlockEntity(pos) match { + case container: IPartHost => Direction.values.map(container.getPart).filter(p => p != null).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isImportBus) case _ => false } - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing) = new Environment(world.getTileEntity(pos).asInstanceOf[IPartHost]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction) = new Environment(world.getBlockEntity(pos).asInstanceOf[IPartHost]) final class Environment(val host: IPartHost) extends ManagedTileEntityEnvironment[IPartHost](host, "me_importbus") with NamedBlock with PartEnvironmentBase { override def preferredName = "me_importbus" diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala index c004b96a06..a1e0070f16 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala @@ -12,29 +12,29 @@ import li.cil.oc.api.machine.Context import li.cil.oc.integration.ManagedTileEntityEnvironment import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverPartInterface extends driver.DriverBlock { - override def worksWith(world: World, pos: BlockPos, side: EnumFacing): Boolean = - world.getTileEntity(pos) match { + override def worksWith(world: World, pos: BlockPos, side: Direction): Boolean = + world.getBlockEntity(pos) match { case container: IPartHost => { - EnumFacing.VALUES.map(container.getPart).filter(p => p != null).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isPartInterface) + Direction.values.map(container.getPart).filter(p => p != null).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isPartInterface) } case _ => false } - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): DriverPartInterface.Environment = { - val host: IPartHost = world.getTileEntity(pos).asInstanceOf[IPartHost] + override def createEnvironment(world: World, pos: BlockPos, side: Direction): DriverPartInterface.Environment = { + val host: IPartHost = world.getBlockEntity(pos).asInstanceOf[IPartHost] val tile = host.asInstanceOf[TileEntity with IPartHost with ISegmentedInventory with IActionHost with IGridHost] val aePos: AEPartLocation = side match { - case EnumFacing.EAST => AEPartLocation.WEST - case EnumFacing.WEST => AEPartLocation.EAST - case EnumFacing.NORTH => AEPartLocation.SOUTH - case EnumFacing.SOUTH => AEPartLocation.NORTH - case EnumFacing.UP => AEPartLocation.DOWN - case EnumFacing.DOWN => AEPartLocation.UP + case Direction.EAST => AEPartLocation.WEST + case Direction.WEST => AEPartLocation.EAST + case Direction.NORTH => AEPartLocation.SOUTH + case Direction.SOUTH => AEPartLocation.NORTH + case Direction.UP => AEPartLocation.DOWN + case Direction.DOWN => AEPartLocation.UP } new Environment(host, tile, aePos) } diff --git a/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala b/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala index 893c8079dd..e34424c16b 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala @@ -1,15 +1,15 @@ package li.cil.oc.integration.appeng import appeng.api.implementations.items.IAEWrench -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.util.EnumHand +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos object EventHandlerAE2 { - def useWrench(player: EntityPlayer, pos: BlockPos, changeDurability: Boolean): Boolean = { - player.getHeldItem(EnumHand.MAIN_HAND).getItem match { - case wrench: IAEWrench => wrench.canWrench(player.getHeldItem(EnumHand.MAIN_HAND), player, pos) + def useWrench(player: PlayerEntity, pos: BlockPos, changeDurability: Boolean): Boolean = { + player.getItemInHand(Hand.MAIN_HAND).getItem match { + case wrench: IAEWrench => wrench.canWrench(player.getItemInHand(Hand.MAIN_HAND), player, pos) case _ => false } } diff --git a/src/main/scala/li/cil/oc/integration/appeng/MachineSource.scala b/src/main/scala/li/cil/oc/integration/appeng/MachineSource.scala index 57ca274ee3..cbc50e12cc 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/MachineSource.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/MachineSource.scala @@ -3,10 +3,10 @@ package li.cil.oc.integration.appeng import java.util.Optional import appeng.api.networking.security.{IActionHost, IActionSource} -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity class MachineSource(val via: IActionHost) extends IActionSource { - def player: Optional[EntityPlayer] = Optional.empty[EntityPlayer] + def player: Optional[PlayerEntity] = Optional.empty[PlayerEntity] def machine: Optional[IActionHost] = Optional.of(this.via) diff --git a/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala b/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala index 9b973b4dce..cba9ed33ef 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala @@ -1,6 +1,5 @@ package li.cil.oc.integration.appeng -import appeng.api.AEApi import li.cil.oc.api import li.cil.oc.api.Driver import li.cil.oc.common.tileentity.Print @@ -14,7 +13,7 @@ object ModAppEng extends ModProxy { api.IMC.registerWrenchTool("li.cil.oc.integration.appeng.EventHandlerAE2.useWrench") api.IMC.registerWrenchToolCheck("li.cil.oc.integration.appeng.EventHandlerAE2.isWrench") - AEApi.instance.registries.movable.whiteListTileEntity(classOf[Print]) + AEUtil.aeApi.get.registries.movable.whiteListTileEntity(classOf[Print]) Driver.add(DriverController) Driver.add(DriverExportBus) diff --git a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala index b131af8527..84cfee3a6d 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala @@ -2,7 +2,6 @@ package li.cil.oc.integration.appeng import java.util -import appeng.api.AEApi import appeng.api.config.Actionable import appeng.api.networking.{IGridHost, IGridNode} import appeng.api.networking.crafting.{ICraftingJob, ICraftingLink, ICraftingRequester} @@ -23,14 +22,18 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ResultWrapper._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.tileentity.TileEntity +import net.minecraft.util.RegistryKey +import net.minecraft.util.ResourceLocation import net.minecraft.util.math.BlockPos -import net.minecraftforge.common.DimensionManager +import net.minecraft.util.registry.{Registry => VanillaRegistry} +import net.minecraft.world.World import net.minecraftforge.common.util.Constants.NBT +import net.minecraftforge.fml.server.ServerLifecycleHooks -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global @@ -44,7 +47,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IActionHost with IGridHos def node: Node private def aeCraftItem(aeItem: IAEItemStack): IAEItemStack = { - val patterns = AEUtil.getGridCrafting(tile.getGridNode(pos).getGrid).getCraftingFor(aeItem, null, 0, tile.getWorld) + val patterns = AEUtil.getGridCrafting(tile.getGridNode(pos).getGrid).getCraftingFor(aeItem, null, 0, tile.getLevel) patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(aeItem))) match { case Some(pattern) => pattern.getOutputs.find(_.isSameType(aeItem)).get case _ => aeItem.copy.setStackSize(0) // Should not be possible, but hey... @@ -67,7 +70,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IActionHost with IGridHos } } - private def reduceSequentialTable(map: scala.collection.mutable.HashMap[_, _]): AnyRef = { + private def reduceSequentialTable[K, V](map: scala.collection.mutable.HashMap[K, V]): AnyRef = { // in place of a table pack, we want a hash map of tuples val tuples = new util.LinkedList[AnyRef]() map.collect { @@ -306,10 +309,10 @@ object NetworkControl { private def withController(f: (TileEntity with IActionHost with IGridHost) => Array[AnyRef]): Array[AnyRef] = { if (delayData != null) { - result(Unit, "waiting for ae network to load") + result((), "waiting for ae network to load") } else { - if (controller == null || controller.isInvalid) { - result(Unit, "no controller") + if (controller == null || controller.isRemoved) { + result((), "no controller") } else { f(controller) } @@ -319,7 +322,7 @@ object NetworkControl { private def withGridNode(f: (IGridNode) => Array[AnyRef]): Array[AnyRef] = { withController(c => Option(c.getGridNode(pos)) match { case Some(grid: IGridNode) => f(grid) - case _ => result(Unit, "no ae grid") + case _ => result((), "no ae grid") }) } @@ -347,7 +350,7 @@ object NetworkControl { val craftingGrid = AEUtil.getGridCrafting(gridNode.getGrid) val source = new MachineSource(controller) - val future = craftingGrid.beginCraftingJob(controller.getWorld, gridNode.getGrid, source, request, null) + val future = craftingGrid.beginCraftingJob(controller.getLevel, gridNode.getGrid, source, request, null) val cpu = if (!cpuName.isEmpty) { craftingGrid.getCpus.collectFirst({ case c if cpuName.equals(c.getName) => c @@ -392,19 +395,19 @@ object NetworkControl { private val MAX_BACKOFF_TICKS = 20 * 5 // 5 seconds private val BACKOFF_SCALE = 2 // multiply by this factor on each failure - private class EphemeralDelayData(val dimension: Int, val x: Int, val y: Int, val z: Int) { + private class EphemeralDelayData(val dimension: RegistryKey[World], val x: Int, val y: Int, val z: Int) { var delay: Int = 1 } private var delayData: EphemeralDelayData = _ // null unless delay loading is active // return true when we do not want to try again, either because we completely failed or we succeeded // return false when things appears just not ready yet - private def tryLoadGrid(dimension: Int, x: Int, y: Int, z: Int): Boolean = { - val world = DimensionManager.getWorld(dimension) + private def tryLoadGrid(dimension: RegistryKey[World], x: Int, y: Int, z: Int): Boolean = { + val world = ServerLifecycleHooks.getCurrentServer.getLevel(dimension) if (world == null) { return false // maybe the dimension isn't loaded yet } - val tileEntity = world.getTileEntity(new BlockPos(x, y, z)) + val tileEntity = world.getBlockEntity(new BlockPos(x, y, z)) if (tileEntity == null) { return false // maybe the chunk isn't loaded yet } @@ -442,17 +445,17 @@ object NetworkControl { } } - override def load(nbt: NBTTagCompound) { - super.load(nbt) - stack = AEUtil.itemStorageChannel.createStack(new ItemStack(nbt)) - links ++= nbt.getTagList(LINKS_KEY, NBT.TAG_COMPOUND).map( - (nbt: NBTTagCompound) => LinkCache.store(AEApi.instance.storage.loadCraftingLink(nbt, this))) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + stack = AEUtil.itemStorageChannel.createStack(ItemStack.of(nbt)) + links ++= nbt.getList(LINKS_KEY, NBT.TAG_COMPOUND).map( + (nbt: CompoundNBT) => LinkCache.store(AEUtil.aeApi.get.storage.loadCraftingLink(nbt, this))) pos = AEPartLocation.fromOrdinal(NbtDataStream.getOptInt(nbt, POS_KEY, AEPartLocation.INTERNAL.ordinal)) - if (nbt.hasKey(DIMENSION_KEY)) { - val dimension = nbt.getInteger(DIMENSION_KEY) - val x = nbt.getInteger(X_KEY) - val y = nbt.getInteger(Y_KEY) - val z = nbt.getInteger(Z_KEY) + if (nbt.contains(DIMENSION_KEY)) { + val dimension = RegistryKey.create(VanillaRegistry.DIMENSION_REGISTRY, new ResourceLocation(nbt.getString(DIMENSION_KEY))) + val x = nbt.getInt(X_KEY) + val y = nbt.getInt(Y_KEY) + val z = nbt.getInt(Z_KEY) delayData = new EphemeralDelayData(dimension, x, y, z) // all of this delay load could have been done nested // but i don't want infinite lambda nesting in cases where the load is never ready @@ -460,21 +463,21 @@ object NetworkControl { } } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - stack.createItemStack().writeToNBT(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + stack.createItemStack().save(nbt) nbt.setNewTagList(LINKS_KEY, links.map((link) => { - val comp = new NBTTagCompound() + val comp = new CompoundNBT() link.writeToNBT(comp) comp })) if (pos != null) - nbt.setInteger(POS_KEY, pos.ordinal) - if (controller != null && !controller.isInvalid) { - nbt.setInteger(DIMENSION_KEY, controller.getWorld.provider.getDimension) - nbt.setInteger(X_KEY, controller.getPos.getX) - nbt.setInteger(Y_KEY, controller.getPos.getY) - nbt.setInteger(Z_KEY, controller.getPos.getZ) + nbt.putInt(POS_KEY, pos.ordinal) + if (controller != null && !controller.isRemoved) { + nbt.putString(DIMENSION_KEY, controller.getLevel.dimension.location.toString) + nbt.putInt(X_KEY, controller.getBlockPos.getX) + nbt.putInt(Y_KEY, controller.getBlockPos.getY) + nbt.putInt(Z_KEY, controller.getBlockPos.getZ) } } } @@ -497,7 +500,7 @@ object NetworkControl { } def asCraft(f: (ICraftingLink) => Array[AnyRef]): Array[AnyRef] = { - if (isComputing) result(Unit, "computing") + if (isComputing) result((), "computing") else link match { case Some(craft: ICraftingLink) if !failed => f(craft) case _ => result(false, reason) @@ -530,17 +533,17 @@ object NetworkControl { private val FAILED_KEY: String = "failed" private val REASON_KEY: String = "reason" - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setBoolean(COMPUTING_KEY, isComputing) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putBoolean(COMPUTING_KEY, isComputing) if (link.nonEmpty) - nbt.setString(LINK_ID_KEY, link.get.getCraftingID) - nbt.setBoolean(FAILED_KEY, failed) - nbt.setString(REASON_KEY, reason) + nbt.putString(LINK_ID_KEY, link.get.getCraftingID) + nbt.putBoolean(FAILED_KEY, failed) + nbt.putString(REASON_KEY, reason) } - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) isComputing = NbtDataStream.getOptBoolean(nbt, COMPUTING_KEY, isComputing) val id = NbtDataStream.getOptString(nbt, LINK_ID_KEY, "") diff --git a/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala b/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala index 572090f758..3775ea6005 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala @@ -25,7 +25,7 @@ trait PartEnvironmentBase extends ManagedEnvironment { val slot = args.optSlot(config, 1, 0) val stack = config.getStackInSlot(slot) result(stack) - case _ => result(Unit, "no matching part") + case _ => result((), "no matching part") } } @@ -60,7 +60,7 @@ trait PartEnvironmentBase extends ManagedEnvironment { config.insertItem(slot, stack, false) context.pause(0.5) result(true) - case _ => result(Unit, "no matching part") + case _ => result((), "no matching part") } } } diff --git a/src/main/scala/li/cil/oc/integration/charset/ModCharset.scala b/src/main/scala/li/cil/oc/integration/charset/ModCharset.scala deleted file mode 100644 index 4c452c54b9..0000000000 --- a/src/main/scala/li/cil/oc/integration/charset/ModCharset.scala +++ /dev/null @@ -1,54 +0,0 @@ -package li.cil.oc.integration.charset - -import li.cil.oc.integration.{ModProxy, Mods} -import li.cil.oc.integration.util.BundledRedstone -import li.cil.oc.integration.util.BundledRedstone.RedstoneProvider -import li.cil.oc.util.BlockPosition -import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import pl.asie.charset.api.wires.{IBundledEmitter, IBundledReceiver, IRedstoneEmitter} - -object ModCharset extends ModProxy with RedstoneProvider { - class BundledRedstoneView(val data: Array[Int], val onChange: () => Unit) extends IBundledEmitter with IBundledReceiver { - override def getBundledSignal: Array[Byte] = data.map(i => i.toByte) - - override def onBundledInputChange(): Unit = { onChange() } - } - - override def getMod = Mods.Charset - - override def initialize(): Unit = { - BundledRedstone.addProvider(this) - } - - override def computeInput(pos: BlockPosition, side: EnumFacing): Int = { - val world = pos.world.get - val npos = pos.toBlockPos.offset(side) - world.getTileEntity(npos) match { - case tile: TileEntity => - if (tile.hasCapability(CapabilitiesCharset.REDSTONE_EMITTER, side.getOpposite)) { - tile.getCapability(CapabilitiesCharset.REDSTONE_EMITTER, side.getOpposite) match { - case emitter: IRedstoneEmitter => return math.min(emitter.getRedstoneSignal, 15) - } - } - 0 - case _ => 0 - } - } - - def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int] = { - val world = pos.world.get - val npos = pos.toBlockPos.offset(side) - world.getTileEntity(npos) match { - case tile: TileEntity => - if (tile.hasCapability(CapabilitiesCharset.BUNDLED_EMITTER, side.getOpposite)) { - tile.getCapability(CapabilitiesCharset.BUNDLED_EMITTER, side.getOpposite) match { - case emitter: IBundledEmitter => - return emitter.getBundledSignal.map(i => i.toInt & 0xFF) - } - } - null - case _ => null - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/computercraft/CallableHelper.java b/src/main/scala/li/cil/oc/integration/computercraft/CallableHelper.java index c37bdf1c26..f4cf70effb 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/CallableHelper.java +++ b/src/main/scala/li/cil/oc/integration/computercraft/CallableHelper.java @@ -22,7 +22,7 @@ public int methodIndex(final String method) throws NoSuchMethodException { return index; } - public Object[] convertArguments(final Arguments args) throws UnsupportedEncodingException { + public static Object[] convertArguments(final Arguments args) throws UnsupportedEncodingException { final Object[] argArray = Iterables.toArray(args, Object.class); for (int i = 0; i < argArray.length; ++i) { if (argArray[i] instanceof byte[]) { diff --git a/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftFileSystem.scala b/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftFileSystem.scala index 0a129d38a3..5a88989028 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftFileSystem.scala +++ b/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftFileSystem.scala @@ -1,5 +1,7 @@ package li.cil.oc.integration.computercraft +import java.nio.channels.Channels + import dan200.computercraft.api.filesystem.IMount import li.cil.oc.server.fs.InputStreamFileSystem @@ -27,7 +29,7 @@ class ComputerCraftFileSystem(val mount: IMount) extends InputStreamFileSystem { // ----------------------------------------------------------------------- // protected def openInputChannel(path: String) = try { - Some(new InputStreamChannel(mount.openForRead(path))) + Some(new InputStreamChannel(Channels.newInputStream(mount.openForRead(path)))) } catch { case _: Throwable => None } diff --git a/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftWritableFileSystem.scala b/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftWritableFileSystem.scala index 12be1052ce..d58e359bce 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftWritableFileSystem.scala +++ b/src/main/scala/li/cil/oc/integration/computercraft/ComputerCraftWritableFileSystem.scala @@ -2,6 +2,7 @@ package li.cil.oc.integration.computercraft import java.io.IOException import java.io.OutputStream +import java.nio.channels.Channels import dan200.computercraft.api.filesystem.IWritableMount import li.cil.oc.api.fs.Mode @@ -27,8 +28,8 @@ class ComputerCraftWritableFileSystem(override val mount: IWritableMount) override protected def openOutputHandle(id: Int, path: String, mode: Mode): Option[OutputHandle] = try { Some(new ComputerCraftOutputHandle(mount, mode match { - case Mode.Append => mount.openForAppend(path) - case Mode.Write => mount.openForWrite(path) + case Mode.Append => Channels.newOutputStream(mount.openForAppend(path)) + case Mode.Write => Channels.newOutputStream(mount.openForWrite(path)) case _ => throw new IllegalArgumentException() }, this, id, path)) } catch { diff --git a/src/main/scala/li/cil/oc/integration/computercraft/ConverterLuaObject.java b/src/main/scala/li/cil/oc/integration/computercraft/ConverterLuaObject.java index d75fe499e3..c5504a2e04 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/ConverterLuaObject.java +++ b/src/main/scala/li/cil/oc/integration/computercraft/ConverterLuaObject.java @@ -1,6 +1,7 @@ package li.cil.oc.integration.computercraft; -import dan200.computercraft.api.lua.ILuaObject; +import dan200.computercraft.api.lua.IDynamicLuaObject; +import dan200.computercraft.api.lua.ObjectArguments; import li.cil.oc.api.driver.Converter; import li.cil.oc.api.machine.Arguments; import li.cil.oc.api.machine.Context; @@ -12,13 +13,13 @@ public final class ConverterLuaObject implements Converter { @Override public void convert(final Object value, final Map output) { - if (value instanceof ILuaObject) { - output.put("value", new LuaObjectValue((ILuaObject) value)); + if (value instanceof IDynamicLuaObject) { + output.put("value", new LuaObjectValue((IDynamicLuaObject) value)); } } public static final class LuaObjectValue extends AbstractValue implements ManagedPeripheral { - private final ILuaObject value; + private final IDynamicLuaObject value; protected final CallableHelper helper; @@ -28,7 +29,7 @@ public LuaObjectValue() { helper = null; } - public LuaObjectValue(final ILuaObject value) { + public LuaObjectValue(final IDynamicLuaObject value) { this.value = value; helper = new CallableHelper(value.getMethodNames()); } @@ -44,8 +45,8 @@ public String[] methods() { public Object[] invoke(final String method, final Context context, final Arguments args) throws Exception { if (value != null) { final int index = helper.methodIndex(method); - final Object[] argArray = helper.convertArguments(args); - return value.callMethod(DriverPeripheral.Environment.UnsupportedLuaContext.instance(), index, argArray); + final Object[] argArray = CallableHelper.convertArguments(args); + return value.callMethod(DriverPeripheral.Environment.UnsupportedLuaContext.instance(), index, new ObjectArguments(argArray)).getResult(); } return new Object[]{null, "ComputerCraft userdata cannot be persisted"}; } diff --git a/src/main/scala/li/cil/oc/integration/computercraft/DriverComputerCraftMedia.scala b/src/main/scala/li/cil/oc/integration/computercraft/DriverComputerCraftMedia.scala index 13c1be5d23..56760e395d 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/DriverComputerCraftMedia.scala +++ b/src/main/scala/li/cil/oc/integration/computercraft/DriverComputerCraftMedia.scala @@ -11,12 +11,12 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common.Slot import li.cil.oc.integration.opencomputers.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT object DriverComputerCraftMedia extends Item { override def worksWith(stack: ItemStack) = stack.getItem.isInstanceOf[IMedia] - override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = if (!host.world.isRemote) { + override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = if (!host.world.isClientSide) { val address = addressFromTag(dataTag(stack)) val mount = fromComputerCraft(stack.getItem.asInstanceOf[IMedia].createDataMount(stack, host.world)) Option(oc.api.FileSystem.asManagedEnvironment(mount, new ComputerCraftLabel(stack), host, Settings.resourceDomain + ":floppy_access")) match { @@ -36,9 +36,9 @@ object DriverComputerCraftMedia extends Item { case ro: IMount => new ComputerCraftFileSystem(ro) } - private def addressFromTag(tag: NBTTagCompound) = - if (tag.hasKey("node") && tag.getCompoundTag("node").hasKey("address")) { - tag.getCompoundTag("node").getString("address") + private def addressFromTag(tag: CompoundNBT) = + if (tag.contains("node") && tag.getCompound("node").contains("address")) { + tag.getCompound("node").getString("address") } else java.util.UUID.randomUUID().toString @@ -51,9 +51,9 @@ object DriverComputerCraftMedia extends Item { media.setLabel(stack, value) } - override def load(nbt: NBTTagCompound) {} + override def loadData(nbt: CompoundNBT) {} - override def save(nbt: NBTTagCompound) {} + override def saveData(nbt: CompoundNBT) {} } } diff --git a/src/main/scala/li/cil/oc/integration/computercraft/DriverPeripheral.java b/src/main/scala/li/cil/oc/integration/computercraft/DriverPeripheral.java index a4368d2193..9eb4402f5e 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/DriverPeripheral.java +++ b/src/main/scala/li/cil/oc/integration/computercraft/DriverPeripheral.java @@ -5,8 +5,13 @@ import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaTask; import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.lua.ObjectArguments; import dan200.computercraft.api.peripheral.IComputerAccess; +import dan200.computercraft.api.peripheral.IWorkMonitor; import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.core.apis.PeripheralAPI; +import dan200.computercraft.core.asm.PeripheralMethod; import li.cil.oc.OpenComputers; import li.cil.oc.Settings; import li.cil.oc.api.FileSystem; @@ -21,9 +26,10 @@ import li.cil.oc.util.Reflection; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.world.World; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -56,9 +62,9 @@ private boolean isBlacklisted(final Object o) { return false; } - private IPeripheral findPeripheral(final World world, final BlockPos pos, final EnumFacing side) { + private IPeripheral findPeripheral(final World world, final BlockPos pos, final Direction side) { try { - final IPeripheral p = dan200.computercraft.ComputerCraft.getPeripheralAt(world, pos, side); + final IPeripheral p = dan200.computercraft.shared.Peripherals.getPeripheral(world, pos, side, cap -> {}); if (!isBlacklisted(p)) { return p; } @@ -69,8 +75,8 @@ private IPeripheral findPeripheral(final World world, final BlockPos pos, final } @Override - public boolean worksWith(final World world, final BlockPos pos, final EnumFacing side) { - final TileEntity tileEntity = world.getTileEntity(pos); + public boolean worksWith(final World world, final BlockPos pos, final Direction side) { + final TileEntity tileEntity = world.getBlockEntity(pos); return tileEntity != null // This ensures we don't get duplicate components, in case the // tile entity is natively compatible with OpenComputers. @@ -83,32 +89,35 @@ public boolean worksWith(final World world, final BlockPos pos, final EnumFacing } @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { + public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final Direction side) { return new Environment(findPeripheral(world, pos, side)); } public static class Environment extends li.cil.oc.api.prefab.AbstractManagedEnvironment implements li.cil.oc.api.network.ManagedPeripheral, NamedBlock { protected final IPeripheral peripheral; - protected final CallableHelper helper; + protected final Map methods; + protected final String[] methodNames; protected final Map accesses = new HashMap(); public Environment(final IPeripheral peripheral) { this.peripheral = peripheral; - helper = new CallableHelper(peripheral.getMethodNames()); + methods = PeripheralAPI.getMethods(peripheral); + methodNames = methods.keySet().toArray(new String[methods.size()]); setNode(Network.newNode(this, Visibility.Network).create()); } @Override public String[] methods() { - return peripheral.getMethodNames(); + return methodNames; } @Override - public Object[] invoke(final String method, final Context context, final Arguments args) throws Exception { - final int index = helper.methodIndex(method); - final Object[] argArray = helper.convertArguments(args); + public Object[] invoke(final String name, final Context context, final Arguments args) throws Exception { + final Object[] argArray = CallableHelper.convertArguments(args); + final PeripheralMethod method = methods.get(name); + if (method == null) throw new NoSuchMethodException(); final FakeComputerAccess access; if (accesses.containsKey(context.node().address())) { access = accesses.get(context.node().address()); @@ -117,13 +126,13 @@ public Object[] invoke(final String method, final Context context, final Argumen // an onConnect for it. Create a temporary access. access = new FakeComputerAccess(this, context); } - return peripheral.callMethod(access, UnsupportedLuaContext.instance(), index, argArray); + return method.apply(peripheral, UnsupportedLuaContext.instance(), access, new ObjectArguments(argArray)).getResult(); } @Override public void onConnect(final Node node) { super.onConnect(node); - if (node.host() instanceof Context) { + if (node.host() instanceof Context && !accesses.containsKey(node.address())) { final FakeComputerAccess access = new FakeComputerAccess(this, (Context) node.host()); accesses.put(node.address(), access); peripheral.attach(access); @@ -237,6 +246,21 @@ public void queueEvent(final String event, final Object[] arguments) { public String getAttachmentName() { return owner.node().address(); } + + @Override + public Map getAvailablePeripherals() { + return Collections.emptyMap(); + } + + @Override + public IPeripheral getAvailablePeripheral(String name) { + return null; + } + + @Override + public IWorkMonitor getMainThreadMonitor() { + throw new UnsupportedOperationException(); + } } /** @@ -259,22 +283,7 @@ public long issueMainThreadTask(ILuaTask task) throws LuaException { } @Override - public Object[] executeMainThreadTask(ILuaTask task) throws LuaException, InterruptedException { - throw new UnsupportedOperationException(); - } - - @Override - public Object[] pullEvent(final String filter) throws LuaException, InterruptedException { - throw new UnsupportedOperationException(); - } - - @Override - public Object[] pullEventRaw(final String filter) throws InterruptedException { - throw new UnsupportedOperationException(); - } - - @Override - public Object[] yield(final Object[] arguments) throws InterruptedException { + public MethodResult executeMainThreadTask(ILuaTask task) throws LuaException { throw new UnsupportedOperationException(); } } diff --git a/src/main/scala/li/cil/oc/integration/computercraft/PeripheralProvider.scala b/src/main/scala/li/cil/oc/integration/computercraft/PeripheralProvider.scala index e0aaacfdef..c5ae02b1d4 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/PeripheralProvider.scala +++ b/src/main/scala/li/cil/oc/integration/computercraft/PeripheralProvider.scala @@ -4,17 +4,21 @@ import dan200.computercraft.api.ComputerCraftAPI import dan200.computercraft.api.peripheral.IPeripheral import dan200.computercraft.api.peripheral.IPeripheralProvider import li.cil.oc.common.tileentity.Relay -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier object PeripheralProvider extends IPeripheralProvider { def init() { ComputerCraftAPI.registerPeripheralProvider(this) } - override def getPeripheral(world: World, blockPos: BlockPos, enumFacing: EnumFacing): IPeripheral = world.getTileEntity(blockPos) match { - case relay: Relay => new RelayPeripheral(relay) - case _ => null + override def getPeripheral(world: World, blockPos: BlockPos, side: Direction): LazyOptional[IPeripheral] = world.getBlockEntity(blockPos) match { + case relay: Relay => LazyOptional.of(new NonNullSupplier[IPeripheral] { + override def get = new RelayPeripheral(relay) + }) + case _ => LazyOptional.empty[IPeripheral] } } diff --git a/src/main/scala/li/cil/oc/integration/computercraft/RelayPeripheral.scala b/src/main/scala/li/cil/oc/integration/computercraft/RelayPeripheral.scala index c030b3b90b..abdf304b49 100644 --- a/src/main/scala/li/cil/oc/integration/computercraft/RelayPeripheral.scala +++ b/src/main/scala/li/cil/oc/integration/computercraft/RelayPeripheral.scala @@ -1,8 +1,11 @@ package li.cil.oc.integration.computercraft +import dan200.computercraft.api.lua.IArguments import dan200.computercraft.api.lua.ILuaContext import dan200.computercraft.api.lua.LuaException +import dan200.computercraft.api.lua.MethodResult import dan200.computercraft.api.peripheral.IComputerAccess +import dan200.computercraft.api.peripheral.IDynamicPeripheral import dan200.computercraft.api.peripheral.IPeripheral import li.cil.oc.Settings import li.cil.oc.api @@ -10,13 +13,14 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.network.Component import li.cil.oc.common.tileentity.Relay import li.cil.oc.util.ResultWrapper._ -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.mapAsJavaMap +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable -class RelayPeripheral(val relay: Relay) extends IPeripheral { +class RelayPeripheral(val relay: Relay) extends IDynamicPeripheral { private val methods = Map[String, (IComputerAccess, ILuaContext, Array[AnyRef]) => Array[AnyRef]]( // Generic modem methods. "open" -> ((computer, context, arguments) => { @@ -111,8 +115,8 @@ class RelayPeripheral(val relay: Relay) extends IPeripheral { override def getMethodNames = methodNames - override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = - try methods(methodNames(method))(computer, context, arguments) catch { + override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: IArguments) = + try MethodResult.of(methods(methodNames(method))(computer, context, arguments.getAll): _*) catch { case e: LuaException => throw e case t: Throwable => t.printStackTrace() @@ -140,7 +144,7 @@ class RelayPeripheral(val relay: Relay) extends IPeripheral { } private def visibleComponents = { - EnumFacing.values().flatMap(side => { + Direction.values().flatMap(side => { val node = relay.sidedNode(side) node.reachableNodes.collect { case component: Component if component.canBeSeenFrom(node) => component diff --git a/src/main/scala/li/cil/oc/integration/ec/DriverBlockInterface.scala b/src/main/scala/li/cil/oc/integration/ec/DriverBlockInterface.scala deleted file mode 100644 index 5d98f3c682..0000000000 --- a/src/main/scala/li/cil/oc/integration/ec/DriverBlockInterface.scala +++ /dev/null @@ -1,36 +0,0 @@ -package li.cil.oc.integration.ec - - -import appeng.api.implementations.tiles.ISegmentedInventory -import appeng.api.networking.IGridHost -import appeng.api.networking.security.IActionHost -import appeng.api.util.AEPartLocation -import li.cil.oc.api.driver.EnvironmentProvider -import li.cil.oc.api.network.ManagedEnvironment -import li.cil.oc.api.prefab.DriverSidedTileEntity -import li.cil.oc.integration.ManagedTileEntityEnvironment -import li.cil.oc.integration.appeng.AEUtil -import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.BlockPos -import net.minecraft.world.World - -object DriverBlockInterface extends DriverSidedTileEntity { - def getTileEntityClass: Class[_] = AEUtil.interfaceClass - - def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntity with ISegmentedInventory with IActionHost with IGridHost]) - - final class Environment(val tile: TileEntity with ISegmentedInventory with IActionHost with IGridHost) extends ManagedTileEntityEnvironment[TileEntity with ISegmentedInventory with IActionHost](tile, "me_interface") with NetworkControl[TileEntity with ISegmentedInventory with IActionHost with IGridHost]{ - override def pos: AEPartLocation = AEPartLocation.INTERNAL - } - - object Provider extends EnvironmentProvider { - override def getEnvironment(stack: ItemStack): Class[_] = - if (AEUtil.isBlockInterface(stack)) - classOf[Environment] - else null - } - -} diff --git a/src/main/scala/li/cil/oc/integration/ec/DriverController.scala b/src/main/scala/li/cil/oc/integration/ec/DriverController.scala deleted file mode 100644 index c6891356f0..0000000000 --- a/src/main/scala/li/cil/oc/integration/ec/DriverController.scala +++ /dev/null @@ -1,38 +0,0 @@ -package li.cil.oc.integration.ec - -import appeng.api.networking.IGridHost -import appeng.api.networking.security.IActionHost -import appeng.api.util.AEPartLocation -import li.cil.oc.api.driver.EnvironmentProvider -import li.cil.oc.api.network.ManagedEnvironment -import li.cil.oc.api.prefab.DriverSidedTileEntity -import li.cil.oc.integration.ManagedTileEntityEnvironment -import li.cil.oc.integration.appeng.AEUtil -import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.BlockPos -import net.minecraft.world.World - -import scala.language.existentials - -object DriverController extends DriverSidedTileEntity { - private type TileController = TileEntity with IActionHost with IGridHost - - def getTileEntityClass = AEUtil.controllerClass - - def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileController]) - - final class Environment(val tile: TileController) extends ManagedTileEntityEnvironment[TileController](tile, "me_controller") with NetworkControl[TileController]{ - override def pos: AEPartLocation = AEPartLocation.INTERNAL - } - - object Provider extends EnvironmentProvider { - override def getEnvironment(stack: ItemStack): Class[_] = - if (AEUtil.isController(stack)) - classOf[Environment] - else null - } - -} diff --git a/src/main/scala/li/cil/oc/integration/ec/ECUtil.scala b/src/main/scala/li/cil/oc/integration/ec/ECUtil.scala deleted file mode 100644 index 7d0b4dbf0f..0000000000 --- a/src/main/scala/li/cil/oc/integration/ec/ECUtil.scala +++ /dev/null @@ -1,13 +0,0 @@ -package li.cil.oc.integration.ec - -import appeng.api.AEApi -import appeng.api.storage.data.IAEFluidStack -import extracells.api.ECApi -import extracells.api.gas.{IAEGasStack, IGasStorageChannel} - -object ECUtil { - val isGasSystemEnabled = ECApi.instance.isGasSystemEnabled - val gasStorageChannel = if (isGasSystemEnabled) AEApi.instance.storage.getStorageChannel[IAEGasStack, IGasStorageChannel](classOf[IGasStorageChannel]) else null - - def canSeeFluidInNetwork(fluid: IAEFluidStack) = fluid != null && ECApi.instance.canFluidSeeInTerminal(fluid.getFluid) -} diff --git a/src/main/scala/li/cil/oc/integration/ec/ModExtraCells.scala b/src/main/scala/li/cil/oc/integration/ec/ModExtraCells.scala deleted file mode 100644 index 0e383bc8b1..0000000000 --- a/src/main/scala/li/cil/oc/integration/ec/ModExtraCells.scala +++ /dev/null @@ -1,18 +0,0 @@ -package li.cil.oc.integration.ec - -import li.cil.oc.api.Driver -import li.cil.oc.integration.Mod -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods - -object ModExtraCells extends ModProxy { - override def getMod: Mod = Mods.ExtraCells - - override def initialize(): Unit = { - Driver.add(DriverController) - Driver.add(DriverBlockInterface) - - Driver.add(DriverController.Provider) - Driver.add(DriverBlockInterface.Provider) - } -} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/ec/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/ec/NetworkControl.scala deleted file mode 100644 index 910c91288d..0000000000 --- a/src/main/scala/li/cil/oc/integration/ec/NetworkControl.scala +++ /dev/null @@ -1,30 +0,0 @@ -package li.cil.oc.integration.ec - -import appeng.api.networking.IGridHost -import appeng.api.networking.security.IActionHost -import appeng.api.util.AEPartLocation -import extracells.api.ECApi -import li.cil.oc.api.machine.Arguments -import li.cil.oc.api.machine.Callback -import li.cil.oc.api.machine.Context -import li.cil.oc.integration.appeng.AEUtil -import li.cil.oc.util.ResultWrapper._ -import net.minecraft.tileentity.TileEntity - -import scala.collection.convert.WrapAsScala._ - -// Note to self: this class is used by ExtraCells (and potentially others), do not rename / drastically change it. -trait NetworkControl[AETile >: Null <: TileEntity with IActionHost with IGridHost] { - def tile: AETile - def pos: AEPartLocation - - @Callback(doc = "function():table -- Get a list of the stored gases in the network.") - def getGasesInNetwork(context: Context, args: Arguments): Array[AnyRef] = { - if (ECUtil.isGasSystemEnabled) - result(AEUtil.getGridStorage(tile.getGridNode(pos).getGrid).getInventory(ECUtil.gasStorageChannel).getStorageList.filter(stack => - stack != null). - map(_.getGasStack).toArray) - else - result(Array.empty) - } -} diff --git a/src/main/scala/li/cil/oc/integration/enderstorage/DriverFrequencyOwner.java b/src/main/scala/li/cil/oc/integration/enderstorage/DriverFrequencyOwner.java index 13ae86bd78..fb0979fd7f 100644 --- a/src/main/scala/li/cil/oc/integration/enderstorage/DriverFrequencyOwner.java +++ b/src/main/scala/li/cil/oc/integration/enderstorage/DriverFrequencyOwner.java @@ -12,7 +12,7 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity; import li.cil.oc.integration.ManagedTileEntityEnvironment; import net.minecraft.world.World; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import java.util.Map; @@ -24,8 +24,8 @@ public Class getTileEntityClass() { } @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((TileFrequencyOwner) world.getTileEntity(pos)); + public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final Direction side) { + return new Environment((TileFrequencyOwner) world.getBlockEntity(pos)); } public static final class Environment extends ManagedTileEntityEnvironment implements NamedBlock { @@ -46,7 +46,7 @@ public int priority() { @Callback(doc = "function():table -- Get the currently set frequency. {left, middle, right}") public Object[] getFrequency(final Context context, final Arguments args) { Object[] frequencies = new Object[3]; - Frequency frequency = tileEntity.frequency; + Frequency frequency = tileEntity.getFrequency(); frequencies[0] = frequency.getLeft().ordinal(); frequencies[1] = frequency.getMiddle().ordinal(); frequencies[2] = frequency.getRight().ordinal(); @@ -79,18 +79,20 @@ public Object[] setFrequency(final Context context, final Arguments args) { EnumColour.fromWoolMeta(left), EnumColour.fromWoolMeta(middle), EnumColour.fromWoolMeta(right), - tileEntity.frequency.owner)); + tileEntity.getFrequency().owner, + tileEntity.getFrequency().ownerName)); return null; } - @Callback(doc = "function():string -- Get the name of the owner, which is usually a player's name or 'global'.") + @Callback(doc = "function():string or nil -- Get the name of the owner, which is usually a player's name or nil.") public Object[] getOwner(final Context context, final Arguments args) { - return new Object[]{tileEntity.frequency.owner}; + Frequency freq = tileEntity.getFrequency(); + return new Object[]{freq.hasOwner() ? freq.ownerName.getString() : null}; } @Callback(doc = "function():table -- Get the currently set frequency as a table of color names.") public Object[] getFrequencyColors(final Context context, final Arguments args){ - return new Object[]{tileEntity.frequency.toArray()}; + return new Object[]{tileEntity.getFrequency().toArray()}; } @Callback(doc = "function():table -- Get a table with the mapping of colors (as Minecraft names) to Frequency numbers. NB: Frequencies are zero based!") diff --git a/src/main/scala/li/cil/oc/integration/forestry/ConverterIAlleles.java b/src/main/scala/li/cil/oc/integration/forestry/ConverterIAlleles.java deleted file mode 100644 index 14d1d6b400..0000000000 --- a/src/main/scala/li/cil/oc/integration/forestry/ConverterIAlleles.java +++ /dev/null @@ -1,41 +0,0 @@ -package li.cil.oc.integration.forestry; - -import com.google.common.collect.Maps; -import forestry.api.genetics.IAlleleSpecies; -import forestry.api.genetics.IMutation; -import li.cil.oc.api.driver.Converter; - -import java.util.Map; - -public class ConverterIAlleles implements Converter { - @Override - public void convert(final Object value, final Map output) { - if (value instanceof IMutation) { - final IMutation mutation = (IMutation) value; - - final IAlleleSpecies allele1 = mutation.getAllele0(); - if (allele1 != null) { - final Map allelMap1 = Maps.newHashMap(); - convert(allele1, allelMap1); - output.put("allele1", allelMap1); - } - final IAlleleSpecies allele2 = mutation.getAllele1(); - if (allele2 != null) { - final Map allelMap2 = Maps.newHashMap(); - convert(allele2, allelMap2); - output.put("allele2", allelMap2); - } - output.put("chance", mutation.getBaseChance()); - output.put("specialConditions", mutation.getSpecialConditions().toArray()); - } - - if (value instanceof IAlleleSpecies) { - convertAlleleSpecies((IAlleleSpecies) value, output); - } - } - - private void convertAlleleSpecies(final IAlleleSpecies value, final Map output) { - output.put("name", value.getAlleleName()); - output.put("uid", value.getUID()); - } -} diff --git a/src/main/scala/li/cil/oc/integration/forestry/ConverterIIndividual.java b/src/main/scala/li/cil/oc/integration/forestry/ConverterIIndividual.java deleted file mode 100644 index ee364286db..0000000000 --- a/src/main/scala/li/cil/oc/integration/forestry/ConverterIIndividual.java +++ /dev/null @@ -1,249 +0,0 @@ -package li.cil.oc.integration.forestry; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; -import forestry.api.apiculture.EnumBeeChromosome; -import forestry.api.apiculture.IAlleleBeeEffect; -import forestry.api.apiculture.IAlleleBeeSpecies; -import forestry.api.apiculture.IBee; -import forestry.api.apiculture.IBeeGenome; -import forestry.api.arboriculture.EnumTreeChromosome; -import forestry.api.arboriculture.IAlleleFruit; -import forestry.api.arboriculture.IAlleleLeafEffect; -import forestry.api.arboriculture.IAlleleTreeSpecies; -import forestry.api.arboriculture.ITree; -import forestry.api.arboriculture.ITreeGenome; -import forestry.api.genetics.IAllele; -import forestry.api.genetics.IAlleleArea; -import forestry.api.genetics.IAlleleBoolean; -import forestry.api.genetics.IAlleleFloat; -import forestry.api.genetics.IAlleleFlowers; -import forestry.api.genetics.IAlleleInteger; -import forestry.api.genetics.IAlleleTolerance; -import forestry.api.genetics.IChromosome; -import forestry.api.genetics.IChromosomeType; -import forestry.api.genetics.IGenome; -import forestry.api.genetics.IIndividual; -import forestry.api.genetics.IIndividualLiving; -import forestry.api.lepidopterology.*; -import li.cil.oc.api.driver.Converter; - -import java.util.Map; - -/* - * Partially copied from: - * https://github.com/OpenMods/OpenPeripheral - */ -public class ConverterIIndividual implements Converter { - private abstract static class GenomeAccess { - public IAllele getAllele(IGenome genome, int chromosome) { - IChromosome[] genotype = genome.getChromosomes(); - IChromosome ch = genotype[chromosome]; - if (ch == null) return null; - return getAllele(ch); - } - - protected abstract IAllele getAllele(IChromosome chromosome); - } - - private static final GenomeAccess ACTIVE = new GenomeAccess() { - @Override - protected IAllele getAllele(IChromosome chromosome) { - return chromosome.getActiveAllele(); - } - }; - - private static final GenomeAccess INACTIVE = new GenomeAccess() { - @Override - protected IAllele getAllele(IChromosome chromosome) { - return chromosome.getInactiveAllele(); - } - }; - - private interface IAlleleConverter { - Object convert(A allele); - } - - private static final Map, IAlleleConverter> converters = - ImmutableMap., IAlleleConverter>builder() - .put(IAlleleFloat.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleFloat allele) { - return allele.getValue(); - } - }) - .put(IAlleleInteger.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleInteger allele) { - return allele.getValue(); - } - }) - .put(IAlleleBoolean.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleBoolean allele) { - return allele.getValue(); - } - }) - .put(IAlleleArea.class, new IAlleleConverter() { - @Override - public Object convert(IAlleleArea allele) { - return allele.getValue(); - } - }) - .build(); - - private abstract static class GenomeReader & IChromosomeType> { - private final G genome; - - public GenomeReader(G genome) { - this.genome = genome; - } - - @SuppressWarnings("unchecked") - protected A getAllele(GenomeAccess access, Class cls, E chromosome) { - Preconditions.checkArgument(chromosome.getAlleleClass() == cls); - IAllele allele = access.getAllele(genome, chromosome.ordinal()); - return (A) allele; - } - - protected Object convertAllele(GenomeAccess access, Class cls, E chromosome) { - A allele = getAllele(access, cls, chromosome); - if (allele == null) return "missing"; - @SuppressWarnings("unchecked") - IAlleleConverter converter = (IAlleleConverter) converters.get(cls); - return converter != null ? converter.convert(allele) : allele.getAlleleName(); - } - - protected abstract void addAlleleInfo(GenomeAccess access, Map result); - - public Map getActiveInfo() { - Map result = Maps.newHashMap(); - addAlleleInfo(ACTIVE, result); - return result; - } - - public Map getInactiveInfo() { - Map result = Maps.newHashMap(); - addAlleleInfo(INACTIVE, result); - return result; - } - } - - private static class BeeGenomeReader extends GenomeReader { - - public BeeGenomeReader(IBeeGenome genome) { - super(genome); - } - - @Override - protected void addAlleleInfo(GenomeAccess access, Map result) { - result.put("species", convertAllele(access, IAlleleBeeSpecies.class, EnumBeeChromosome.SPECIES)); - result.put("speed", convertAllele(access, IAlleleFloat.class, EnumBeeChromosome.SPEED)); - result.put("lifespan", convertAllele(access, IAlleleInteger.class, EnumBeeChromosome.LIFESPAN)); - result.put("fertility", convertAllele(access, IAlleleInteger.class, EnumBeeChromosome.FERTILITY)); - result.put("temperatureTolerance", convertAllele(access, IAlleleTolerance.class, EnumBeeChromosome.TEMPERATURE_TOLERANCE)); - result.put("neverSleeps", convertAllele(access, IAlleleBoolean.class, EnumBeeChromosome.NEVER_SLEEPS)); - result.put("humidityTolerance", convertAllele(access, IAlleleTolerance.class, EnumBeeChromosome.HUMIDITY_TOLERANCE)); - result.put("toleratesRain", convertAllele(access, IAlleleBoolean.class, EnumBeeChromosome.TOLERATES_RAIN)); - result.put("caveDwelling", convertAllele(access, IAlleleBoolean.class, EnumBeeChromosome.CAVE_DWELLING)); - result.put("flowerProvider", convertAllele(access, IAlleleFlowers.class, EnumBeeChromosome.FLOWER_PROVIDER)); - result.put("flowering", convertAllele(access, IAlleleInteger.class, EnumBeeChromosome.FLOWERING)); - result.put("effect", convertAllele(access, IAlleleBeeEffect.class, EnumBeeChromosome.EFFECT)); - result.put("territory", convertAllele(access, IAlleleArea.class, EnumBeeChromosome.TERRITORY)); - } - } - - private static class ButterflyGenomeReader extends GenomeReader { - - public ButterflyGenomeReader(IButterflyGenome genome) { - super(genome); - } - - @Override - protected void addAlleleInfo(GenomeAccess access, Map result) { - result.put("species", convertAllele(access, IAlleleButterflySpecies.class, EnumButterflyChromosome.SPECIES)); - result.put("size", convertAllele(access, IAlleleFloat.class, EnumButterflyChromosome.SIZE)); - result.put("speed", convertAllele(access, IAlleleFloat.class, EnumButterflyChromosome.SPEED)); - result.put("lifespan", convertAllele(access, IAlleleInteger.class, EnumButterflyChromosome.LIFESPAN)); - result.put("metabolism", convertAllele(access, IAlleleInteger.class, EnumButterflyChromosome.METABOLISM)); - result.put("fertility", convertAllele(access, IAlleleInteger.class, EnumButterflyChromosome.FERTILITY)); - result.put("temperatureTolerance", convertAllele(access, IAlleleTolerance.class, EnumButterflyChromosome.TEMPERATURE_TOLERANCE)); - result.put("humidityTolerance", convertAllele(access, IAlleleTolerance.class, EnumButterflyChromosome.HUMIDITY_TOLERANCE)); - result.put("nocturnal", convertAllele(access, IAlleleBoolean.class, EnumButterflyChromosome.NOCTURNAL)); - result.put("tolerantFlyer", convertAllele(access, IAlleleBoolean.class, EnumButterflyChromosome.TOLERANT_FLYER)); - result.put("fireResist", convertAllele(access, IAlleleBoolean.class, EnumButterflyChromosome.FIRE_RESIST)); - result.put("flowerProvider", convertAllele(access, IAlleleFlowers.class, EnumButterflyChromosome.FLOWER_PROVIDER)); - result.put("effect", convertAllele(access, IAlleleButterflyEffect.class, EnumButterflyChromosome.EFFECT)); - result.put("cocoon", convertAllele(access, IAlleleButterflyCocoon.class, EnumButterflyChromosome.COCOON)); - } - } - - private static class TreeGenomeReader extends GenomeReader { - - public TreeGenomeReader(ITreeGenome genome) { - super(genome); - } - - @Override - protected void addAlleleInfo(GenomeAccess access, Map result) { - result.put("species", convertAllele(access, IAlleleTreeSpecies.class, EnumTreeChromosome.SPECIES)); - result.put("fireproof", convertAllele(access, IAlleleBoolean.class, EnumTreeChromosome.FIREPROOF)); - result.put("height", convertAllele(access, IAlleleFloat.class, EnumTreeChromosome.HEIGHT)); - result.put("fertility", convertAllele(access, IAlleleFloat.class, EnumTreeChromosome.FERTILITY)); - result.put("fruits", convertAllele(access, IAlleleFruit.class, EnumTreeChromosome.FRUITS)); - result.put("yield", convertAllele(access, IAlleleFloat.class, EnumTreeChromosome.YIELD)); - result.put("sappiness", convertAllele(access, IAlleleFloat.class, EnumTreeChromosome.SAPPINESS)); - result.put("effect", convertAllele(access, IAlleleLeafEffect.class, EnumTreeChromosome.EFFECT)); - result.put("maturation", convertAllele(access, IAlleleInteger.class, EnumTreeChromosome.MATURATION)); - result.put("girth", convertAllele(access, IAlleleInteger.class, EnumTreeChromosome.GIRTH)); - } - } - - @Override - public void convert(final Object value, final Map output) { - if (value instanceof IIndividual) { - IIndividual individual = (IIndividual) value; - output.put("displayName", individual.getDisplayName()); - output.put("ident", individual.getIdent()); - - final boolean isAnalyzed = individual.isAnalyzed(); - output.put("isAnalyzed", isAnalyzed); - output.put("isSecret", individual.isSecret()); - GenomeReader genomeReader = null; - - if (individual instanceof IIndividualLiving) { - IIndividualLiving living = (IIndividualLiving) individual; - output.put("health", living.getHealth()); - output.put("maxHealth", living.getMaxHealth()); - } - - if (individual instanceof IBee) { - IBee bee = (IBee) individual; - output.put("type", "bee"); - output.put("canSpawn", bee.canSpawn()); - output.put("generation", bee.getGeneration()); - output.put("hasEffect", bee.hasEffect()); - output.put("isAlive", bee.isAlive()); - output.put("isNatural", bee.isNatural()); - - if (isAnalyzed) genomeReader = new BeeGenomeReader(bee.getGenome()); - } else if (individual instanceof IButterfly) { - IButterfly butterfly = (IButterfly) individual; - output.put("type", "butterfly"); - output.put("size", butterfly.getSize()); - if (isAnalyzed) genomeReader = new ButterflyGenomeReader(butterfly.getGenome()); - } else if (individual instanceof ITree) { - ITree tree = (ITree) individual; - output.put("type", "tree"); - output.put("plantType", tree.getDisplayName()); - if (isAnalyzed) genomeReader = new TreeGenomeReader(tree.getGenome()); - } - - if (genomeReader != null) { - output.put("active", genomeReader.getActiveInfo()); - output.put("inactive", genomeReader.getInactiveInfo()); - } - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala b/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala deleted file mode 100644 index fd2e64f677..0000000000 --- a/src/main/scala/li/cil/oc/integration/forestry/ConverterItemStack.scala +++ /dev/null @@ -1,17 +0,0 @@ -package li.cil.oc.integration.forestry - -import java.util - -import forestry.api.genetics.AlleleManager -import li.cil.oc.api.driver.Converter -import net.minecraft.item.ItemStack - -import scala.collection.convert.WrapAsScala._ - -object ConverterItemStack extends Converter { - override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]): Unit = value match { - case stack: ItemStack if AlleleManager.alleleRegistry.isIndividual(stack) => - output += "individual" -> AlleleManager.alleleRegistry.getIndividual(stack) - case _ => - } -} diff --git a/src/main/scala/li/cil/oc/integration/forestry/DriverAnalyzer.scala b/src/main/scala/li/cil/oc/integration/forestry/DriverAnalyzer.scala deleted file mode 100644 index 6cf3f9dfe3..0000000000 --- a/src/main/scala/li/cil/oc/integration/forestry/DriverAnalyzer.scala +++ /dev/null @@ -1,35 +0,0 @@ -package li.cil.oc.integration.forestry -import forestry.core.tiles.TileAnalyzer -import li.cil.oc.api.driver.NamedBlock -import li.cil.oc.api.machine.Arguments -import li.cil.oc.api.machine.Callback -import li.cil.oc.api.machine.Context -import li.cil.oc.api.prefab.DriverSidedTileEntity -import li.cil.oc.integration.ManagedTileEntityEnvironment -import li.cil.oc.util.ResultWrapper._ -import net.minecraft.world.World -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.BlockPos -import forestry.api.genetics.AlleleManager - -class DriverAnalyzer extends DriverSidedTileEntity { - override def getTileEntityClass = classOf[TileAnalyzer] - - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing) = new Environment(world.getTileEntity(pos).asInstanceOf[TileAnalyzer]) - - final class Environment(tileEntity: TileAnalyzer) extends ManagedTileEntityEnvironment[TileAnalyzer](tileEntity, "forestry_analyzer") with NamedBlock { - override def preferredName = "forestry_analyzer" - - override def priority = 0 - - @Callback(doc = "function():boolean -- Get whether the analyzer can work.") - def isWorking(context: Context, args: Arguments): Array[AnyRef] = result(tileEntity.hasWork) - - @Callback(doc = "function():double -- Get the progress of the current operation.") - def getProgress(context: Context, args: Arguments): Array[AnyRef] = result(1.0 - tileEntity.getProgressScaled(100) / 100.0) - - @Callback(doc = "function():table -- Get info on the currently present bee.") - def getIndividualOnDisplay(context: Context, args: Arguments): Array[AnyRef] = result(AlleleManager.alleleRegistry.getIndividual(tileEntity.getIndividualOnDisplay)) - } - -} diff --git a/src/main/scala/li/cil/oc/integration/forestry/DriverBeeHouse.java b/src/main/scala/li/cil/oc/integration/forestry/DriverBeeHouse.java deleted file mode 100644 index 673ca6c9e0..0000000000 --- a/src/main/scala/li/cil/oc/integration/forestry/DriverBeeHouse.java +++ /dev/null @@ -1,163 +0,0 @@ -package li.cil.oc.integration.forestry; - -import com.google.common.collect.Sets; -import forestry.api.apiculture.IBeeHousing; -import forestry.api.genetics.AlleleManager; -import forestry.api.genetics.IAllele; -import forestry.api.genetics.IAlleleSpecies; -import forestry.api.genetics.IMutation; -import forestry.api.genetics.ISpeciesRoot; -import li.cil.oc.api.driver.NamedBlock; -import li.cil.oc.api.machine.Arguments; -import li.cil.oc.api.machine.Callback; -import li.cil.oc.api.machine.Context; -import li.cil.oc.api.network.ManagedEnvironment; -import li.cil.oc.api.prefab.DriverSidedTileEntity; -import li.cil.oc.integration.ManagedTileEntityEnvironment; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -public class DriverBeeHouse extends DriverSidedTileEntity { - @Override - public Class getTileEntityClass() { - return IBeeHousing.class; - } - - @Override - public ManagedEnvironment createEnvironment(World world, BlockPos pos, EnumFacing side) { - return new Environment((IBeeHousing) world.getTileEntity(pos)); - } - - public static final class Environment extends ManagedTileEntityEnvironment implements NamedBlock { - public Environment(final IBeeHousing tileEntity) { - super(tileEntity, "bee_housing"); - } - - @Override - public String preferredName() { - return "bee_housing"; - } - - @Override - public int priority() { - return 0; - } - - @Callback(doc = "function():boolean -- Can the bees breed?") - public Object[] canBreed(final Context context, final Arguments args) { - return new Object[]{tileEntity.getBeekeepingLogic().canWork()}; - } - - @Callback(doc = "function():table -- Get the drone") - public Object[] getDrone(final Context context, final Arguments args) { - final ItemStack drone = tileEntity.getBeeInventory().getDrone(); - if (drone != null) { - return new Object[]{AlleleManager.alleleRegistry.getIndividual(drone)}; - } - return null; - } - - @Callback(doc = "function():table -- Get the queen") - public Object[] getQueen(final Context context, final Arguments args) { - final ItemStack queen = tileEntity.getBeeInventory().getQueen(); - if (queen != null) { - return new Object[]{AlleleManager.alleleRegistry.getIndividual(queen)}; - } - return null; - } - - @Callback(doc = "function():table -- Get the full breeding list thingy.") - public Object[] getBeeBreedingData(final Context context, final Arguments args) { - final ISpeciesRoot beeRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); - if (beeRoot == null) { - return null; - } - - final Set> result = Sets.newHashSet(); - for (IMutation mutation : beeRoot.getMutations(false)) { - final HashMap mutationMap = new HashMap(); - - final IAllele allele1 = mutation.getAllele0(); - if (allele1 != null) { - mutationMap.put("allele1", allele1.getAlleleName()); - } - - final IAllele allele2 = mutation.getAllele1(); - if (allele2 != null) { - mutationMap.put("allele2", allele2.getAlleleName()); - } - - mutationMap.put("chance", mutation.getBaseChance()); - mutationMap.put("specialConditions", mutation - .getSpecialConditions().toArray()); - - final IAllele[] template = mutation.getTemplate(); - if (template != null && template.length > 0) { - mutationMap.put("result", template[0].getAlleleName()); - } - result.add(mutationMap); - } - return new Object[]{result}; - } - - @Callback(doc = "function():table -- Get all known bees mutations") - public Object[] listAllSpecies(final Context context, final Arguments args) { - final ISpeciesRoot beeRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); - if (beeRoot == null) { - return null; - } - - final Set result = Sets.newHashSet(); - for (IMutation mutation : beeRoot.getMutations(false)) { - final IAllele[] template = mutation.getTemplate(); - if (template == null || template.length <= 0) { - continue; - } - - final IAllele allele = template[0]; - if (!(allele instanceof IAlleleSpecies)) { - continue; - } - - result.add((IAlleleSpecies) allele); - } - return new Object[]{result}; - } - - @Callback(doc = "function(beeName:string):table -- Get the parents for a particular mutation") - public Object[] getBeeParents(final Context context, final Arguments args) { - final ISpeciesRoot beeRoot = AlleleManager.alleleRegistry.getSpeciesRoot("rootBees"); - if (beeRoot == null) { - return null; - } - - final Set result = Sets.newHashSet(); - final String childType = args.checkString(0).toLowerCase(); - for (IMutation mutation : beeRoot.getMutations(false)) { - final IAllele[] template = mutation.getTemplate(); - if (template == null || template.length < 1) { - continue; - } - - final IAllele allele = template[0]; - if (!(allele instanceof IAlleleSpecies)) { - continue; - } - - final IAlleleSpecies species = (IAlleleSpecies) allele; - final String uid = species.getUID().toLowerCase(); - final String localizedName = species.getAlleleName().toLowerCase(); - if (localizedName.equals(childType) || uid.equals(childType)) { - result.add(mutation); - } - } - return new Object[]{result}; - } - } -} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala b/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala deleted file mode 100644 index c23dc4e9a4..0000000000 --- a/src/main/scala/li/cil/oc/integration/forestry/ModForestry.scala +++ /dev/null @@ -1,17 +0,0 @@ -package li.cil.oc.integration.forestry - -import li.cil.oc.api.Driver -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods - -object ModForestry extends ModProxy { - override def getMod = Mods.Forestry - - override def initialize() { - Driver.add(new ConverterIAlleles) - Driver.add(new ConverterIIndividual) - Driver.add(ConverterItemStack) - Driver.add(new DriverAnalyzer) - Driver.add(new DriverBeeHouse) - } -} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/ic2/ConverterElectricItem.java b/src/main/scala/li/cil/oc/integration/ic2/ConverterElectricItem.java deleted file mode 100644 index 981a3faf69..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/ConverterElectricItem.java +++ /dev/null @@ -1,27 +0,0 @@ -package li.cil.oc.integration.ic2; - -import ic2.api.item.ElectricItem; -import ic2.api.item.IElectricItem; -import li.cil.oc.api.driver.Converter; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; - -import java.util.Map; - -public class ConverterElectricItem implements Converter { - @Override - public void convert(final Object value, final Map output) { - if (value instanceof ItemStack) { - final ItemStack stack = (ItemStack) value; - final Item item = stack.getItem(); - if (item instanceof IElectricItem) { - final IElectricItem electricItem = (IElectricItem) item; - output.put("canProvideEnergy", electricItem.canProvideEnergy(stack)); - output.put("charge", ElectricItem.manager.getCharge(stack)); - output.put("maxCharge", electricItem.getMaxCharge(stack)); - output.put("tier", electricItem.getTier(stack)); - output.put("transferLimit", electricItem.getTransferLimit(stack)); - } - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/DriverEnergy.java b/src/main/scala/li/cil/oc/integration/ic2/DriverEnergy.java deleted file mode 100644 index aa8cc52bc9..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/DriverEnergy.java +++ /dev/null @@ -1,61 +0,0 @@ -package li.cil.oc.integration.ic2; - -import ic2.core.block.TileEntityBlock; -import ic2.core.block.comp.Energy; -import li.cil.oc.api.driver.DriverBlock; -import li.cil.oc.api.machine.Arguments; -import li.cil.oc.api.machine.Callback; -import li.cil.oc.api.machine.Context; -import li.cil.oc.api.network.ManagedEnvironment; -import li.cil.oc.integration.ManagedTileEntityEnvironment; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; - -public final class DriverEnergy implements DriverBlock { - @Override - public boolean worksWith(final World world, final BlockPos pos, final EnumFacing side) { - final TileEntity tileEntity = world.getTileEntity(pos); - if (tileEntity instanceof TileEntityBlock) { - final TileEntityBlock tileEntityBlock = (TileEntityBlock) tileEntity; - return tileEntityBlock.hasComponent(Energy.class); - } - return false; - } - - @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((TileEntityBlock) world.getTileEntity(pos)); - } - - public static final class Environment extends ManagedTileEntityEnvironment { - public Environment(final TileEntityBlock tileEntity) { - super(tileEntity, "ic2_energy"); - } - - @Callback - public Object[] getCapacity(final Context context, final Arguments args) { - final Energy energy = tileEntity.getComponent(Energy.class); - return new Object[]{energy.getCapacity()}; - } - - @Callback - public Object[] getEnergy(final Context context, final Arguments args) { - final Energy energy = tileEntity.getComponent(Energy.class); - return new Object[]{energy.getEnergy()}; - } - - @Callback - public Object[] getSinkTier(final Context context, final Arguments args) { - final Energy energy = tileEntity.getComponent(Energy.class); - return new Object[]{energy.getSinkTier()}; - } - - @Callback - public Object[] getSourceTier(final Context context, final Arguments args) { - final Energy energy = tileEntity.getComponent(Energy.class); - return new Object[]{energy.getSourceTier()}; - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/DriverEnergyConductor.java b/src/main/scala/li/cil/oc/integration/ic2/DriverEnergyConductor.java deleted file mode 100644 index 8485265cb5..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/DriverEnergyConductor.java +++ /dev/null @@ -1,50 +0,0 @@ -package li.cil.oc.integration.ic2; - -import ic2.api.energy.tile.IEnergyConductor; -import li.cil.oc.api.machine.Arguments; -import li.cil.oc.api.machine.Callback; -import li.cil.oc.api.machine.Context; -import li.cil.oc.api.network.ManagedEnvironment; -import li.cil.oc.api.prefab.DriverSidedTileEntity; -import li.cil.oc.integration.ManagedTileEntityEnvironment; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; - -public final class DriverEnergyConductor extends DriverSidedTileEntity { - @Override - public Class getTileEntityClass() { - return IEnergyConductor.class; - } - - @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((IEnergyConductor) world.getTileEntity(pos)); - } - - public static final class Environment extends ManagedTileEntityEnvironment { - public Environment(final IEnergyConductor tileEntity) { - super(tileEntity, "energy_conductor"); - } - - @Callback - public Object[] getConductionLoss(final Context context, final Arguments args) { - return new Object[]{tileEntity.getConductionLoss()}; - } - - @Callback - public Object[] getConductorBreakdownEnergy(final Context context, final Arguments args) { - return new Object[]{tileEntity.getConductorBreakdownEnergy()}; - } - - @Callback - public Object[] getInsulationBreakdownEnergy(final Context context, final Arguments args) { - return new Object[]{tileEntity.getInsulationBreakdownEnergy()}; - } - - @Callback - public Object[] getInsulationEnergyAbsorption(final Context context, final Arguments args) { - return new Object[]{tileEntity.getInsulationEnergyAbsorption()}; - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/DriverMassFab.java b/src/main/scala/li/cil/oc/integration/ic2/DriverMassFab.java deleted file mode 100644 index a32e3e45e7..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/DriverMassFab.java +++ /dev/null @@ -1,47 +0,0 @@ -package li.cil.oc.integration.ic2; - -import ic2.core.block.comp.Energy; -import ic2.core.block.machine.tileentity.TileEntityMatter; -import li.cil.oc.api.driver.NamedBlock; -import li.cil.oc.api.machine.Arguments; -import li.cil.oc.api.machine.Callback; -import li.cil.oc.api.machine.Context; -import li.cil.oc.api.prefab.AbstractManagedEnvironment; -import li.cil.oc.api.prefab.DriverSidedTileEntity; -import li.cil.oc.integration.ManagedTileEntityEnvironment; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; - -public final class DriverMassFab extends DriverSidedTileEntity { - @Override - public Class getTileEntityClass() { - return TileEntityMatter.class; - } - - @Override - public AbstractManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((TileEntityMatter) world.getTileEntity(pos)); - } - - public static final class Environment extends ManagedTileEntityEnvironment implements NamedBlock { - public Environment(final TileEntityMatter tileEntity) { - super(tileEntity, "mass_fab"); - } - - @Override - public String preferredName() { - return "mass_fab"; - } - - @Override - public int priority() { - return 0; - } - - @Callback - public Object[] getProgress(final Context context, final Arguments args) { - return new Object[]{Math.min(100 * tileEntity.getComponent(Energy.class).getFillRatio(), 100)}; - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/DriverReactor.java b/src/main/scala/li/cil/oc/integration/ic2/DriverReactor.java deleted file mode 100644 index 0d7231ea8a..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/DriverReactor.java +++ /dev/null @@ -1,67 +0,0 @@ -package li.cil.oc.integration.ic2; - - -import ic2.api.reactor.IReactor; -import li.cil.oc.api.driver.NamedBlock; -import li.cil.oc.api.machine.Arguments; -import li.cil.oc.api.machine.Callback; -import li.cil.oc.api.machine.Context; -import li.cil.oc.api.network.ManagedEnvironment; -import li.cil.oc.api.prefab.DriverSidedTileEntity; -import li.cil.oc.integration.ManagedTileEntityEnvironment; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; - -public final class DriverReactor extends DriverSidedTileEntity { - @Override - public Class getTileEntityClass() { - return IReactor.class; - } - - @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((IReactor) world.getTileEntity(pos)); - } - - public static final class Environment extends ManagedTileEntityEnvironment implements NamedBlock { - public Environment(final IReactor tileEntity) { - super(tileEntity, "reactor"); - } - - @Override - public String preferredName() { - return "reactor"; - } - - @Override - public int priority() { - return 0; - } - - @Callback(doc = "function():number -- Get the reactor's heat.") - public Object[] getHeat(final Context context, final Arguments args) { - return new Object[]{tileEntity.getHeat()}; - } - - @Callback(doc = "function():number -- Get the reactor's maximum heat before exploding.") - public Object[] getMaxHeat(final Context context, final Arguments args) { - return new Object[]{tileEntity.getMaxHeat()}; - } - - @Callback(doc = "function():number -- Get the reactor's energy output. Not multiplied with the base EU/t value.") - public Object[] getReactorEnergyOutput(final Context context, final Arguments args) { - return new Object[]{tileEntity.getReactorEnergyOutput()}; - } - - @Callback(doc = "function():number -- Get the reactor's base EU/t value.") - public Object[] getReactorEUOutput(final Context context, final Arguments args) { - return new Object[]{tileEntity.getReactorEUEnergyOutput()}; - } - - @Callback(doc = "function():boolean -- Get whether the reactor is active and supposed to produce energy.") - public Object[] producesEnergy(final Context context, final Arguments args) { - return new Object[]{tileEntity.produceEnergy()}; - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/DriverReactorChamber.java b/src/main/scala/li/cil/oc/integration/ic2/DriverReactorChamber.java deleted file mode 100644 index d6d2a5a559..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/DriverReactorChamber.java +++ /dev/null @@ -1,87 +0,0 @@ -package li.cil.oc.integration.ic2; - -import ic2.api.reactor.IReactor; -import ic2.api.reactor.IReactorChamber; -import li.cil.oc.api.driver.NamedBlock; -import li.cil.oc.api.machine.Arguments; -import li.cil.oc.api.machine.Callback; -import li.cil.oc.api.machine.Context; -import li.cil.oc.api.network.ManagedEnvironment; -import li.cil.oc.api.prefab.DriverSidedTileEntity; -import li.cil.oc.integration.ManagedTileEntityEnvironment; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; - -public final class DriverReactorChamber extends DriverSidedTileEntity { - @Override - public Class getTileEntityClass() { - return IReactorChamber.class; - } - - @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((IReactorChamber) world.getTileEntity(pos)); - } - - public static final class Environment extends ManagedTileEntityEnvironment implements NamedBlock { - public Environment(final IReactorChamber tileEntity) { - super(tileEntity, "reactor_chamber"); - } - - @Override - public String preferredName() { - return "reactor_chamber"; - } - - @Override - public int priority() { - return 0; - } - - @Callback(doc = "function():number -- Get the reactor's heat.") - public Object[] getHeat(final Context context, final Arguments args) { - final IReactor reactor = tileEntity.getReactorInstance(); - if (reactor != null) { - return new Object[]{reactor.getHeat()}; - } else { - return new Object[]{0}; - } - } - - @Callback(doc = "function():number -- Get the reactor's maximum heat before exploding.") - public Object[] getMaxHeat(final Context context, final Arguments args) { - final IReactor reactor = tileEntity.getReactorInstance(); - if (reactor != null) { - return new Object[]{tileEntity.getReactorInstance().getMaxHeat()}; - } else { - return new Object[]{0}; - } - } - - @Callback(doc = "function():number -- Get the reactor's energy output. Not multiplied with the base EU/t value.") - public Object[] getReactorEnergyOutput(final Context context, final Arguments args) { - final IReactor reactor = tileEntity.getReactorInstance(); - if (reactor != null) { - return new Object[]{tileEntity.getReactorInstance().getReactorEnergyOutput()}; - } else { - return new Object[]{0}; - } - } - - @Callback(doc = "function():number -- Get the reactor's base EU/t value.") - public Object[] getReactorEUOutput(final Context context, final Arguments args) { - return new Object[]{tileEntity.getReactorInstance().getReactorEUEnergyOutput()}; - } - - @Callback(doc = "function():boolean -- Get whether the reactor is active and supposed to produce energy.") - public Object[] producesEnergy(final Context context, final Arguments args) { - final IReactor reactor = tileEntity.getReactorInstance(); - if (reactor != null) { - return new Object[]{tileEntity.getReactorInstance().produceEnergy()}; - } else { - return new Object[]{false}; - } - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/DriverReactorRedstonePort.java b/src/main/scala/li/cil/oc/integration/ic2/DriverReactorRedstonePort.java deleted file mode 100644 index 103a7adecf..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/DriverReactorRedstonePort.java +++ /dev/null @@ -1,102 +0,0 @@ -package li.cil.oc.integration.ic2; - -import ic2.api.reactor.IReactor; -import ic2.core.block.comp.FluidReactorLookup; -import ic2.core.block.reactor.tileentity.TileEntityReactorRedstonePort; -import li.cil.oc.api.driver.NamedBlock; -import li.cil.oc.api.machine.Arguments; -import li.cil.oc.api.machine.Callback; -import li.cil.oc.api.machine.Context; -import li.cil.oc.api.network.ManagedEnvironment; -import li.cil.oc.api.prefab.DriverSidedTileEntity; -import li.cil.oc.integration.ManagedTileEntityEnvironment; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; -import net.minecraft.world.World; - -public final class DriverReactorRedstonePort extends DriverSidedTileEntity { - @Override - public Class getTileEntityClass() { - return TileEntityReactorRedstonePort.class; - } - - @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((TileEntityReactorRedstonePort) world.getTileEntity(pos)); - } - - public static final class Environment extends ManagedTileEntityEnvironment implements NamedBlock { - public Environment(final TileEntityReactorRedstonePort tileEntity) { - super(tileEntity, "reactor_redstone_port"); - } - - @Override - public String preferredName() { - return "reactor_redstone_port"; - } - - @Override - public int priority() { - return 0; - } - - private IReactor getReactor() { - final FluidReactorLookup lookup = tileEntity.getComponent(FluidReactorLookup.class); - if (lookup != null) { - return lookup.getReactor(); - } else { - return null; - } - } - - @Callback(doc = "function():number -- Get the reactor's heat.") - public Object[] getHeat(final Context context, final Arguments args) { - final IReactor reactor = getReactor(); - if (reactor != null) { - return new Object[]{reactor.getHeat()}; - } else { - return new Object[]{0}; - } - } - - @Callback(doc = "function():number -- Get the reactor's maximum heat before exploding.") - public Object[] getMaxHeat(final Context context, final Arguments args) { - final IReactor reactor = getReactor(); - if (reactor != null) { - return new Object[]{reactor.getMaxHeat()}; - } else { - return new Object[]{0}; - } - } - - @Callback(doc = "function():number -- Get the reactor's energy output. Not multiplied with the base EU/t value.") - public Object[] getReactorEnergyOutput(final Context context, final Arguments args) { - final IReactor reactor = getReactor(); - if (reactor != null) { - return new Object[]{reactor.getReactorEnergyOutput()}; - } else { - return new Object[]{0}; - } - } - - @Callback(doc = "function():number -- Get the reactor's base EU/t value.") - public Object[] getReactorEUOutput(final Context context, final Arguments args) { - final IReactor reactor = getReactor(); - if (reactor != null) { - return new Object[]{getReactor().getReactorEUEnergyOutput()}; - } else { - return new Object[]{false}; - } - } - - @Callback(doc = "function():boolean -- Get whether the reactor is active and supposed to produce energy.") - public Object[] producesEnergy(final Context context, final Arguments args) { - final IReactor reactor = getReactor(); - if (reactor != null) { - return new Object[]{reactor.produceEnergy()}; - } else { - return new Object[]{false}; - } - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/ElectricItemManager.scala b/src/main/scala/li/cil/oc/integration/ic2/ElectricItemManager.scala deleted file mode 100644 index cb0f135116..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/ElectricItemManager.scala +++ /dev/null @@ -1,54 +0,0 @@ -package li.cil.oc.integration.ic2 - -import ic2.api.item.IElectricItem -import ic2.api.item.IElectricItemManager -import li.cil.oc.Settings -import li.cil.oc.api.driver.item.Chargeable -import li.cil.oc.integration.util.Power -import net.minecraft.entity.EntityLivingBase -import net.minecraft.item.ItemStack - -object ElectricItemManager extends IElectricItemManager { - override def getCharge(stack: ItemStack): Double = { - if (stack == null) 0 - else stack.getItem match { - case chargeable: Chargeable => - Power.toEU(Int.MaxValue + chargeable.charge(stack, -Int.MaxValue, true)) - case _ => 0 - } - } - - override def charge(stack: ItemStack, amount: Double, tier: Int, ignoreTransferLimit: Boolean, simulate: Boolean): Double = { - if (stack == null) 0 - else stack.getItem match { - case chargeable: Chargeable => - val limitedAmount = if (ignoreTransferLimit) math.min(Int.MaxValue, amount) else math.min(amount, Settings.get.chargeRateTablet) - limitedAmount - Power.toEU(chargeable.charge(stack, Power.fromEU(limitedAmount), simulate)) - case _ => 0 - } - } - - override def discharge(stack: ItemStack, amount: Double, tier: Int, ignoreTransferLimit: Boolean, externally: Boolean, simulate: Boolean): Double = { - 0.0 // TODO if we ever need it... - } - - override def chargeFromArmor(stack: ItemStack, entity: EntityLivingBase): Unit = {} - - override def canUse(stack: ItemStack, amount: Double): Boolean = getCharge(stack) >= amount - - override def use(stack: ItemStack, amount: Double, entity: EntityLivingBase): Boolean = canUse(stack, amount) && { - false // TODO if we ever need it... - } - - override def getToolTip(stack: ItemStack): String = "" - - override def getMaxCharge(stack: ItemStack): Double = Option(stack).map(_.getItem) match { - case Some(item: IElectricItem) => item.getMaxCharge(stack) - case _ => 0 - } - - override def getTier(stack: ItemStack): Int = Option(stack).map(_.getItem) match { - case Some(item: IElectricItem) => item.getTier(stack) - case _ => 0 - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/EventHandlerIndustrialCraft2.scala b/src/main/scala/li/cil/oc/integration/ic2/EventHandlerIndustrialCraft2.scala deleted file mode 100644 index 6aae5711b9..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/EventHandlerIndustrialCraft2.scala +++ /dev/null @@ -1,80 +0,0 @@ -package li.cil.oc.integration.ic2 - -import ic2.api.item.ElectricItem -import ic2.api.item.IElectricItem -import ic2.api.item.ISpecialElectricItem -import ic2.core.item.tool.ItemToolWrench -import li.cil.oc.api.event.RobotUsedToolEvent -import li.cil.oc.integration.util.Power -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.ItemStack -import net.minecraft.util.math.BlockPos -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -object EventHandlerIndustrialCraft2 { - @SubscribeEvent - def onRobotApplyDamageRate(e: RobotUsedToolEvent.ApplyDamageRate) { - val optManagerBefore = e.toolBeforeUse.getItem match { - case item: ISpecialElectricItem => Option(item.getManager(e.toolBeforeUse)) - case item: IElectricItem => Option(ElectricItem.manager) - case _ => None - } - val optManagerAfter = e.toolAfterUse.getItem match { - case item: ISpecialElectricItem => Option(item.getManager(e.toolAfterUse)) - case item: IElectricItem => Option(ElectricItem.manager) - case _ => None - } - (optManagerBefore, optManagerAfter) match { - case (Some(managerBefore), Some(managerAfter)) => - val damage = managerBefore.getCharge(e.toolBeforeUse) - managerAfter.getCharge(e.toolAfterUse) - if (damage > 0) { - val actualDamage = damage * e.getDamageRate - val repairedDamage = - if (e.agent.player.getRNG.nextDouble() > 0.5) - damage - math.floor(actualDamage).toInt - else - damage - math.ceil(actualDamage).toInt - managerAfter.charge(e.toolAfterUse, repairedDamage, Int.MaxValue, true, false) - } - case _ => - } - } - - def getDurability(stack: ItemStack): Double = { - stack.getItem match { - case item: ISpecialElectricItem => item.getManager(stack).getCharge(stack) / item.getManager(stack).getMaxCharge(stack) - case item: IElectricItem => ElectricItem.manager.getCharge(stack) / item.getMaxCharge(stack) - case _ => Double.NaN - } - } - - def useWrench(player: EntityPlayer, pos: BlockPos, changeDurability: Boolean): Boolean = { - player.getHeldItemMainhand.getItem match { - case wrench: ItemToolWrench => - if (changeDurability) { - wrench.damage(player.getHeldItemMainhand, 1, player) - true - } - else wrench.canTakeDamage(player.getHeldItemMainhand, 1) - case _ => false - } - } - - def isWrench(stack: ItemStack): Boolean = stack.getItem.isInstanceOf[ItemToolWrench] - - def canCharge(stack: ItemStack): Boolean = stack.getItem match { - case chargeable: IElectricItem => chargeable.getMaxCharge(stack) > 0 - case _ => false - } - - def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = { - (stack.getItem match { - case item: ISpecialElectricItem => Option(item.getManager(stack)) - case item: IElectricItem => Option(ElectricItem.manager) - case _ => None - }) match { - case Some(manager) => amount - Power.fromEU(manager.charge(stack, Power.toEU(amount), Int.MaxValue, true, false)) - case _ => amount - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/ic2/ModIndustrialCraft2.scala b/src/main/scala/li/cil/oc/integration/ic2/ModIndustrialCraft2.scala deleted file mode 100644 index bd93491027..0000000000 --- a/src/main/scala/li/cil/oc/integration/ic2/ModIndustrialCraft2.scala +++ /dev/null @@ -1,43 +0,0 @@ -package li.cil.oc.integration.ic2 - -import li.cil.oc.api -import li.cil.oc.api.Driver -import li.cil.oc.api.prefab.DriverSidedTileEntity -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods -import net.minecraftforge.common.MinecraftForge - -object ModIndustrialCraft2 extends ModProxy { - override def getMod = Mods.IndustrialCraft2 - - def tryAddDriver(driver: DriverSidedTileEntity): Unit = { - try { - if (driver.getTileEntityClass != null) - Driver.add(driver) - } catch { - case _: Exception => - } - } - - override def initialize() { - api.IMC.registerToolDurabilityProvider("li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.getDurability") - api.IMC.registerWrenchTool("li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.useWrench") - api.IMC.registerWrenchToolCheck("li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.isWrench") - api.IMC.registerItemCharge( - "IndustrialCraft2", - "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.canCharge", - "li.cil.oc.integration.ic2.EventHandlerIndustrialCraft2.charge") - - MinecraftForge.EVENT_BUS.register(EventHandlerIndustrialCraft2) - - tryAddDriver(new DriverReactorRedstonePort) - tryAddDriver(new DriverMassFab) - - Driver.add(new DriverEnergyConductor) - Driver.add(new DriverEnergy) - Driver.add(new DriverReactor) - Driver.add(new DriverReactorChamber) - - Driver.add(new ConverterElectricItem) - } -} diff --git a/src/main/scala/li/cil/oc/integration/jei/CallbackDocHandler.scala b/src/main/scala/li/cil/oc/integration/jei/CallbackDocHandler.scala index 47c394485e..3a7af620b8 100644 --- a/src/main/scala/li/cil/oc/integration/jei/CallbackDocHandler.scala +++ b/src/main/scala/li/cil/oc/integration/jei/CallbackDocHandler.scala @@ -2,25 +2,30 @@ package li.cil.oc.integration.jei import java.util -import javax.annotation.Nonnull import com.google.common.base.Strings +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.server.machine.Callbacks -import mezz.jei.api.IGuiHelper -import mezz.jei.api.IModRegistry -import mezz.jei.api.gui.IDrawable +import mezz.jei.api.constants.VanillaTypes import mezz.jei.api.gui.IRecipeLayout +import mezz.jei.api.gui.drawable.IDrawable +import mezz.jei.api.gui.drawable.IDrawableAnimated.StartDirection +import mezz.jei.api.helpers.IGuiHelper import mezz.jei.api.ingredients.IIngredients -import mezz.jei.api.recipe._ +import mezz.jei.api.recipe.category.IRecipeCategory +import mezz.jei.api.registration.IRecipeRegistration import net.minecraft.client.Minecraft import net.minecraft.item.ItemStack +import net.minecraft.util.ICharacterConsumer import net.minecraft.util.ResourceLocation +import net.minecraft.util.text.CharacterManager.ISliceAcceptor +import net.minecraft.util.text.Style import net.minecraft.util.text.TextFormatting -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object CallbackDocHandler { @@ -29,7 +34,7 @@ object CallbackDocHandler { private val VexPattern = """(?s)^function(\(.*?\).*?); (.*)$""".r - def getRecipes(registry: IModRegistry): util.List[CallbackDocRecipe] = registry.getIngredientRegistry.getIngredients(classOf[ItemStack]).collect { + def getRecipes(registration: IRecipeRegistration): util.List[CallbackDocRecipe] = registration.getIngredientManager.getAllIngredients(VanillaTypes.ITEM).collect { case stack: ItemStack => val callbacks = api.Driver.environmentsFor(stack).flatMap(getCallbacks).toBuffer @@ -73,22 +78,15 @@ object CallbackDocHandler { } else Seq.empty - protected def wrap(line: String, width: Int): util.List[String] = Minecraft.getMinecraft.fontRenderer.listFormattedStringToWidth(line, width) - - object CallbackDocRecipeHandler extends IRecipeWrapperFactory[CallbackDocRecipe] { - override def getRecipeWrapper(recipe: CallbackDocRecipe): CallbackDocRecipe = recipe + protected def wrap(line: String, width: Int): util.List[String] = { + val list = new util.ArrayList[String] + Minecraft.getInstance.font.getSplitter.splitLines(line, width, Style.EMPTY, true, new ISliceAcceptor { + override def accept(style: Style, start: Int, end: Int) = list.add(line.substring(start, end)) + }) + list } - class CallbackDocRecipe(val stack: ItemStack, val page: String) extends BlankRecipeWrapper { - - override def getIngredients(ingredients: IIngredients): Unit = ingredients.setInputs(classOf[ItemStack], List(stack)) - - override def drawInfo(@Nonnull minecraft: Minecraft, recipeWidth: Int, recipeHeight: Int, mouseX: Int, mouseY: Int): Unit = { - for ((text, line) <- page.lines.zipWithIndex) { - minecraft.fontRenderer.drawString(text, 4, 4 + line * (minecraft.fontRenderer.FONT_HEIGHT + 1), 0x333333, false) - } - } - } + class CallbackDocRecipe(val stack: ItemStack, val page: String) object CallbackDocRecipeCategory extends IRecipeCategory[CallbackDocRecipe] { val recipeWidth: Int = 160 @@ -102,18 +100,30 @@ object CallbackDocHandler { guiHelper.createTickTimer(20, 1, true), 0, 16) } + override def getRecipeClass = classOf[CallbackDocRecipe] + override def getIcon: IDrawable = icon override def getBackground: IDrawable = background + override def setIngredients(recipeWrapper: CallbackDocRecipe, ingredients: IIngredients) { + ingredients.setInput(VanillaTypes.ITEM, recipeWrapper.stack) + } + override def setRecipe(recipeLayout: IRecipeLayout, recipeWrapper: CallbackDocRecipe, ingredients: IIngredients) { } - override def getTitle = "OpenComputers API" + override def draw(recipeWrapper: CallbackDocRecipe, stack: MatrixStack, mouseX: Double, mouseY: Double): Unit = { + val minecraft = Minecraft.getInstance + for ((text, line) <- recipeWrapper.page.lines.zipWithIndex) { + minecraft.font.draw(stack, text, 4, 4 + line * (minecraft.font.lineHeight + 1), 0x333333) + } + } - override def getUid = "oc.api" + @Deprecated + override def getTitle = "OpenComputers API" - override def getModName: String = OpenComputers.Name + override def getUid = new ResourceLocation(OpenComputers.ID, "part_api") } } diff --git a/src/main/scala/li/cil/oc/integration/jei/DrawableAnimatedIcon.scala b/src/main/scala/li/cil/oc/integration/jei/DrawableAnimatedIcon.scala index 3d5c170d10..4efb5ce3f3 100644 --- a/src/main/scala/li/cil/oc/integration/jei/DrawableAnimatedIcon.scala +++ b/src/main/scala/li/cil/oc/integration/jei/DrawableAnimatedIcon.scala @@ -1,12 +1,13 @@ package li.cil.oc.integration.jei -import mezz.jei.api.gui.IDrawableAnimated +import com.mojang.blaze3d.matrix.MatrixStack import mezz.jei.api.gui.ITickTimer +import mezz.jei.api.gui.drawable.IDrawableAnimated import net.minecraft.client.Minecraft -import net.minecraft.client.gui.Gui +import net.minecraft.client.gui.AbstractGui import net.minecraft.util.ResourceLocation -import net.minecraftforge.fml.relauncher.Side -import net.minecraftforge.fml.relauncher.SideOnly +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn /** * Used to simulate an animated texture. @@ -21,21 +22,18 @@ class DrawableAnimatedIcon(resourceLocation: ResourceLocation, u: Int, v: Int, w override def getHeight: Int = height + paddingTop + paddingBottom - @SideOnly(Side.CLIENT) - override def draw(minecraft: Minecraft): Unit = draw(minecraft, 0, 0) - - @SideOnly(Side.CLIENT) - override def draw(minecraft: Minecraft, xOffset: Int, yOffset: Int) { + @OnlyIn(Dist.CLIENT) + override def draw(stack: MatrixStack, xOffset: Int, yOffset: Int) { val animationValue = tickTimer.getValue val uOffsetTotal = uOffset * animationValue val vOffsetTotal = vOffset * animationValue - minecraft.getTextureManager.bindTexture(resourceLocation) + Minecraft.getInstance.getTextureManager.bind(resourceLocation) val x = xOffset + this.paddingLeft val y = yOffset + this.paddingTop val u = this.u + uOffsetTotal val v = this.v + vOffsetTotal - Gui.drawModalRectWithCustomSizedTexture(x, y, u, v, width, height, textureWidth, textureHeight) + AbstractGui.blit(stack, x, y, u, v, width, height, textureWidth, textureHeight) } } diff --git a/src/main/scala/li/cil/oc/integration/jei/LootDiskCyclingRecipeHandler.scala b/src/main/scala/li/cil/oc/integration/jei/LootDiskCyclingRecipeHandler.scala deleted file mode 100644 index a35885eee0..0000000000 --- a/src/main/scala/li/cil/oc/integration/jei/LootDiskCyclingRecipeHandler.scala +++ /dev/null @@ -1,33 +0,0 @@ -package li.cil.oc.integration.jei - -import java.util - -import li.cil.oc.Constants -import li.cil.oc.api -import li.cil.oc.common.Loot -import li.cil.oc.common.recipe.LootDiskCyclingRecipe -import mezz.jei.api.ingredients.IIngredients -import mezz.jei.api.recipe._ -import net.minecraft.item.ItemStack - -import scala.collection.convert.WrapAsJava._ - -object LootDiskCyclingRecipeHandler extends IRecipeWrapperFactory[LootDiskCyclingRecipe] { - override def getRecipeWrapper(recipe: LootDiskCyclingRecipe): IRecipeWrapper = new LootDiskCyclingRecipeWrapper(recipe) - - class LootDiskCyclingRecipeWrapper(val recipe: LootDiskCyclingRecipe) extends BlankRecipeWrapper { - - def getInputs: util.List[util.List[ItemStack]] = List(seqAsJavaList(Loot.disksForCycling), seqAsJavaList(List(api.Items.get(Constants.ItemName.Wrench).createItemStack(1)))) - - def getOutputs: util.List[ItemStack] = Loot.disksForCycling.toList - - override def getIngredients(ingredients: IIngredients): Unit = { - ingredients.setInputLists(classOf[ItemStack], getInputs) - ingredients.setOutputs(classOf[ItemStack], getOutputs) - } - } - -} - - - diff --git a/src/main/scala/li/cil/oc/integration/jei/ManualUsageHandler.scala b/src/main/scala/li/cil/oc/integration/jei/ManualUsageHandler.scala index 9e419587df..fafbd84abf 100644 --- a/src/main/scala/li/cil/oc/integration/jei/ManualUsageHandler.scala +++ b/src/main/scala/li/cil/oc/integration/jei/ManualUsageHandler.scala @@ -2,84 +2,84 @@ package li.cil.oc.integration.jei import java.util -import javax.annotation.Nonnull +import com.mojang.blaze3d.matrix.MatrixStack import li.cil.oc.Localization import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api -import mezz.jei.api.IGuiHelper -import mezz.jei.api.IModRegistry -import mezz.jei.api.gui.IDrawable +import mezz.jei.api.constants.VanillaTypes import mezz.jei.api.gui.IRecipeLayout +import mezz.jei.api.gui.drawable.IDrawable +import mezz.jei.api.helpers.IGuiHelper import mezz.jei.api.ingredients.IIngredients -import mezz.jei.api.recipe._ +import mezz.jei.api.recipe.category.IRecipeCategory +import mezz.jei.api.registration.IRecipeRegistration import net.minecraft.client.Minecraft import net.minecraft.item.ItemStack import net.minecraft.util.ResourceLocation -import net.minecraftforge.fml.client.config.GuiButtonExt +import net.minecraft.client.gui.widget.button.Button +import org.lwjgl.glfw.GLFW -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ object ManualUsageHandler { - def getRecipes(registry: IModRegistry): util.List[ManualUsageRecipe] = registry.getIngredientRegistry.getIngredients(classOf[ItemStack]).collect { + def getRecipes(registration: IRecipeRegistration): util.List[ManualUsageRecipe] = registration.getIngredientManager.getAllIngredients(VanillaTypes.ITEM).collect { case stack: ItemStack => api.Manual.pathFor(stack) match { case s: String => Option(new ManualUsageRecipe(stack, s)) case _ => None } }.flatten.toList - object ManualUsageRecipeHandler extends IRecipeWrapperFactory[ManualUsageRecipe] { - override def getRecipeWrapper(recipe: ManualUsageRecipe): ManualUsageRecipe = recipe - } - - class ManualUsageRecipe(val stack: ItemStack, val path: String) extends BlankRecipeWrapper { - lazy val button = new GuiButtonExt(0, (160 - 100) / 2, 10, 100, 20, Localization.localizeImmediately("nei.usage.oc.Manual")) - - override def getIngredients(ingredients: IIngredients): Unit = ingredients.setInputs(classOf[ItemStack], List(stack)) - - override def drawInfo(@Nonnull minecraft: Minecraft, recipeWidth: Int, recipeHeight: Int, mouseX: Int, mouseY: Int): Unit = { - button.displayString = Localization.localizeImmediately("nei.usage.oc.Manual") - button.x = (recipeWidth - button.width) / 2 - button.y = button.height / 2 - button.drawButton(minecraft, mouseX, mouseY, 1) - } - - override def handleClick(@Nonnull minecraft: Minecraft, mouseX: Int, mouseY: Int, mouseButton: Int): Boolean = { - if (button.mousePressed(minecraft, mouseX, mouseY)) { - minecraft.player.closeScreen() - api.Manual.openFor(minecraft.player) - api.Manual.navigate(path) - true - } - else false - } - } + class ManualUsageRecipe(val stack: ItemStack, val path: String) object ManualUsageRecipeCategory extends IRecipeCategory[ManualUsageRecipe] { val recipeWidth: Int = 160 val recipeHeight: Int = 125 private var background: IDrawable = _ private var icon: IDrawable = _ + private val button = new Button((160 - 100) / 2, 10, 100, 20, Localization.localizeLater("nei.usage.oc.Manual"), new Button.IPressable { + override def onPress(b: Button) = () + }) def initialize(guiHelper: IGuiHelper) { background = guiHelper.createBlankDrawable(recipeWidth, recipeHeight) - icon = guiHelper.createDrawable(new ResourceLocation(Settings.resourceDomain, "textures/items/manual.png"), 0, 0, 16, 16, 16, 16) + icon = guiHelper.drawableBuilder(new ResourceLocation(Settings.resourceDomain, "textures/items/manual.png"), 0, 0, 16, 16).setTextureSize(16, 16).build() } + override def getRecipeClass = classOf[ManualUsageRecipe] + override def getBackground: IDrawable = background override def getIcon: IDrawable = icon + override def setIngredients(recipeWrapper: ManualUsageRecipe, ingredients: IIngredients) { + ingredients.setInput(VanillaTypes.ITEM, recipeWrapper.stack) + } + override def setRecipe(recipeLayout: IRecipeLayout, recipeWrapper: ManualUsageRecipe, ingredients: IIngredients) { } - override def getTitle = "OpenComputers Manual" + override def draw(recipeWrapper: ManualUsageRecipe, stack: MatrixStack, mouseX: Double, mouseY: Double) { + button.render(stack, mouseX.toInt, mouseY.toInt, 0) + } + + override def handleClick(recipeWrapper: ManualUsageRecipe, mouseX: Double, mouseY: Double, mouseButton: Int): Boolean = { + if (mouseButton == GLFW.GLFW_MOUSE_BUTTON_LEFT || button.isMouseOver(mouseX, mouseY)) { + val minecraft = Minecraft.getInstance + minecraft.player.closeContainer() + api.Manual.openFor(minecraft.player) + api.Manual.navigate(recipeWrapper.path) + true + } + else false + } - override def getUid = "oc.manual" + @Deprecated + override def getTitle = "OpenComputers Manual" - override def getModName: String = OpenComputers.Name + override def getUid = new ResourceLocation(OpenComputers.ID, "manual") } } diff --git a/src/main/scala/li/cil/oc/integration/jei/ModJEI.scala b/src/main/scala/li/cil/oc/integration/jei/ModJEI.scala index 36955dff9e..8bd2316574 100644 --- a/src/main/scala/li/cil/oc/integration/jei/ModJEI.scala +++ b/src/main/scala/li/cil/oc/integration/jei/ModJEI.scala @@ -1,30 +1,31 @@ package li.cil.oc.integration.jei import li.cil.oc.common.EventHandler -import mezz.jei.api.IJeiRuntime -import mezz.jei.api.ingredients.IIngredientRegistry +import mezz.jei.api.constants.VanillaTypes +import mezz.jei.api.runtime.IIngredientManager +import mezz.jei.api.runtime.IJeiRuntime import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsJava.seqAsJavaList +import scala.collection.JavaConverters.seqAsJavaList import scala.collection.mutable import scala.collection.mutable.ArrayBuffer -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ModJEI { var runtime: Option[IJeiRuntime] = None - var ingredientRegistry: Option[IIngredientRegistry] = None + var ingredientRegistry: Option[IIngredientManager] = None private val disksForRuntime: ArrayBuffer[ItemStack] = mutable.ArrayBuffer.empty private var scheduled: Boolean = false def addDiskAtRuntime(stack: ItemStack): Unit = ingredientRegistry.foreach { registry => - if (!registry.getIngredients(classOf[ItemStack]).exists(ItemStack.areItemStacksEqual(_, stack))) { + if (!registry.getAllIngredients(VanillaTypes.ITEM).exists(ItemStack.matches(_, stack))) { disksForRuntime += stack if (!scheduled) { EventHandler.scheduleClient { () => - ingredientRegistry.foreach(_.addIngredientsAtRuntime(classOf[ItemStack], seqAsJavaList(disksForRuntime))) + ingredientRegistry.foreach(_.addIngredientsAtRuntime(VanillaTypes.ITEM, seqAsJavaList(disksForRuntime))) disksForRuntime.clear() scheduled = false } diff --git a/src/main/scala/li/cil/oc/integration/jei/ModPluginOpenComputers.scala b/src/main/scala/li/cil/oc/integration/jei/ModPluginOpenComputers.scala index 8e968b42a8..31904a553c 100644 --- a/src/main/scala/li/cil/oc/integration/jei/ModPluginOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/jei/ModPluginOpenComputers.scala @@ -1,75 +1,74 @@ package li.cil.oc.integration.jei import li.cil.oc.Constants +import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api.Items -import li.cil.oc.common.recipe.LootDiskCyclingRecipe +import li.cil.oc.client.gui.Relay import li.cil.oc.integration.jei.CallbackDocHandler.CallbackDocRecipe import li.cil.oc.integration.jei.ManualUsageHandler.ManualUsageRecipe -import li.cil.oc.integration.util.ItemBlacklist import li.cil.oc.integration.util.ItemSearch import li.cil.oc.util.StackOption -import mezz.jei.api.IJeiRuntime import mezz.jei.api.IModPlugin -import mezz.jei.api.IModRegistry -import mezz.jei.api.ISubtypeRegistry -import mezz.jei.api.ISubtypeRegistry.ISubtypeInterpreter -import mezz.jei.api.JEIPlugin -import mezz.jei.api.ingredients.IModIngredientRegistration -import mezz.jei.api.recipe.{IRecipeCategoryRegistration, VanillaRecipeCategoryUid} -import net.minecraft.client.gui.inventory.GuiContainer +import mezz.jei.api.JeiPlugin +import mezz.jei.api.constants.VanillaTypes +import mezz.jei.api.ingredients.subtypes.IIngredientSubtypeInterpreter +import mezz.jei.api.ingredients.subtypes.UidContext +import mezz.jei.api.registration.IAdvancedRegistration +import mezz.jei.api.registration.IGuiHandlerRegistration +import mezz.jei.api.registration.IRecipeCategoryRegistration +import mezz.jei.api.registration.IRecipeRegistration +import mezz.jei.api.registration.ISubtypeRegistration +import mezz.jei.api.runtime.IIngredientManager +import mezz.jei.api.runtime.IJeiRuntime +import net.minecraft.client.gui.screen.inventory.ContainerScreen import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.ResourceLocation -@JEIPlugin +import scala.collection.JavaConverters._ + +@JeiPlugin class ModPluginOpenComputers extends IModPlugin { + override def getPluginUid = new ResourceLocation(OpenComputers.ID, "jei_plugin") + override def registerCategories(registry: IRecipeCategoryRegistration): Unit = { registry.addRecipeCategories(ManualUsageHandler.ManualUsageRecipeCategory) registry.addRecipeCategories(CallbackDocHandler.CallbackDocRecipeCategory) - } - override def register(registry: IModRegistry) { - if (Settings.get.lootRecrafting) { - registry.handleRecipes(classOf[LootDiskCyclingRecipe], LootDiskCyclingRecipeHandler, VanillaRecipeCategoryUid.CRAFTING) - } + override def registerRecipes(registration: IRecipeRegistration) { + registration.addRecipes(ManualUsageHandler.getRecipes(registration), ManualUsageHandler.ManualUsageRecipeCategory.getUid) + registration.addRecipes(CallbackDocHandler.getRecipes(registration), CallbackDocHandler.CallbackDocRecipeCategory.getUid) + } - ItemBlacklist.hiddenItems.foreach(getter => registry.getJeiHelpers.getIngredientBlacklist.addIngredientToBlacklist(getter())) + override def registerGuiHandlers(registration: IGuiHandlerRegistration) = { + registration.addGuiContainerHandler(classOf[Relay], RelayGuiHandler) + } + override def registerAdvanced(registration: IAdvancedRegistration) = { // This could go into the Description category, but Manual should always be in front of the Callback doc. - ManualUsageHandler.ManualUsageRecipeCategory.initialize(registry.getJeiHelpers.getGuiHelper) - CallbackDocHandler.CallbackDocRecipeCategory.initialize(registry.getJeiHelpers.getGuiHelper) - - registry.handleRecipes(classOf[ManualUsageRecipe], ManualUsageHandler.ManualUsageRecipeHandler, ManualUsageHandler.ManualUsageRecipeCategory.getUid) - registry.handleRecipes(classOf[CallbackDocRecipe], CallbackDocHandler.CallbackDocRecipeHandler, CallbackDocHandler.CallbackDocRecipeCategory.getUid) - - registry.addRecipes(ManualUsageHandler.getRecipes(registry), ManualUsageHandler.ManualUsageRecipeCategory.getUid) - registry.addRecipes(CallbackDocHandler.getRecipes(registry), CallbackDocHandler.CallbackDocRecipeCategory.getUid) - - registry.addAdvancedGuiHandlers(RelayGuiHandler) - - ModJEI.ingredientRegistry = Option(registry.getIngredientRegistry) + ManualUsageHandler.ManualUsageRecipeCategory.initialize(registration.getJeiHelpers.getGuiHelper) + CallbackDocHandler.CallbackDocRecipeCategory.initialize(registration.getJeiHelpers.getGuiHelper) } - private var stackUnderMouse: (GuiContainer, Int, Int) => StackOption = _ + private var stackUnderMouse: (ContainerScreen[_], Int, Int) => StackOption = _ override def onRuntimeAvailable(jeiRuntime: IJeiRuntime) { if (stackUnderMouse == null) { ItemSearch.stackFocusing += ((container, mouseX, mouseY) => stackUnderMouse(container, mouseX, mouseY)) } - stackUnderMouse = (container, mouseX, mouseY) => StackOption(jeiRuntime.getItemListOverlay.getStackUnderMouse) + stackUnderMouse = (container, mouseX, mouseY) => StackOption(jeiRuntime.getIngredientListOverlay.getIngredientUnderMouse(VanillaTypes.ITEM)) ModJEI.runtime = Option(jeiRuntime) + ModJEI.ingredientRegistry = Option(jeiRuntime.getIngredientManager) } - override def registerIngredients(registry: IModIngredientRegistration) { - } - - override def registerItemSubtypes(subtypeRegistry: ISubtypeRegistry) { + override def registerItemSubtypes(subtypeRegistry: ISubtypeRegistration) { def useNBT(names: String*) = names.map(name => { val info = Items.get(name) - Option(info.item).getOrElse(Item.getItemFromBlock(info.block)) + Option(info.item).getOrElse(info.block.asItem()) }).filter(_ != null).distinct.foreach(subtypeRegistry.useNbtForSubtypes(_)) // Only the preconfigured blocks and items have to be here. @@ -81,16 +80,14 @@ class ModPluginOpenComputers extends IModPlugin { Constants.ItemName.Tablet ) - subtypeRegistry.registerSubtypeInterpreter(Items.get(Constants.ItemName.Floppy).item(), new ISubtypeInterpreter { - override def apply(stack: ItemStack): String = { - if (!stack.hasTagCompound) return null - val compound: NBTTagCompound = stack.getTagCompound - val data = new NBTTagCompound + subtypeRegistry.registerSubtypeInterpreter(Items.get(Constants.ItemName.Floppy).item(), new IIngredientSubtypeInterpreter[ItemStack] { + override def apply(stack: ItemStack, ctx: UidContext): String = { + if (!stack.hasTag) return IIngredientSubtypeInterpreter.NONE // Separate loot disks from normal floppies - if (compound.hasKey(Settings.namespace + "lootFactory")) { - data.setTag(Settings.namespace + "lootFactory", compound.getTag(Settings.namespace + "lootFactory")) + Option(stack.getTag.get(Settings.namespace + "lootFactory")) match { + case Some(lf) => lf.toString + case None => IIngredientSubtypeInterpreter.NONE } - if (data.hasNoTags) null else data.toString } }) } diff --git a/src/main/scala/li/cil/oc/integration/jei/RelayGuiHandler.scala b/src/main/scala/li/cil/oc/integration/jei/RelayGuiHandler.scala index 860c4ee6db..569dba0975 100644 --- a/src/main/scala/li/cil/oc/integration/jei/RelayGuiHandler.scala +++ b/src/main/scala/li/cil/oc/integration/jei/RelayGuiHandler.scala @@ -1,20 +1,18 @@ package li.cil.oc.integration.jei -import java.awt.Rectangle import java.util import li.cil.oc.client.gui.Relay -import mezz.jei.api.gui.IAdvancedGuiHandler +import mezz.jei.api.gui.handlers.IGuiContainerHandler +import net.minecraft.client.renderer.Rectangle2d -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ -object RelayGuiHandler extends IAdvancedGuiHandler[Relay] { +object RelayGuiHandler extends IGuiContainerHandler[Relay] { - override def getGuiContainerClass: Class[Relay] = classOf[Relay] - - override def getGuiExtraAreas(gui: Relay): util.List[Rectangle] = List( - new Rectangle(gui.windowX + gui.tabPosition.getX, gui.windowY + gui.tabPosition.getY, gui.tabPosition.getWidth, gui.tabPosition.getHeight) + override def getGuiExtraAreas(gui: Relay): util.List[Rectangle2d] = List( + new Rectangle2d(gui.windowX + gui.tabPosition.getX, gui.windowY + gui.tabPosition.getY, gui.tabPosition.getWidth, gui.tabPosition.getHeight) ) - override def getIngredientUnderMouse(guiContainer: Relay, mouseX: Int, mouseY: Int) = null + override def getIngredientUnderMouse(guiContainer: Relay, mouseX: Double, mouseY: Double) = null } diff --git a/src/main/scala/li/cil/oc/integration/mekanism/ConverterGasStack.scala b/src/main/scala/li/cil/oc/integration/mekanism/ConverterGasStack.scala new file mode 100644 index 0000000000..2bb4727391 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mekanism/ConverterGasStack.scala @@ -0,0 +1,29 @@ +package li.cil.oc.integration.mekanism + +import java.util + +import li.cil.oc.Settings +import li.cil.oc.api +import mekanism.api.MekanismAPI +import mekanism.api.chemical.gas.Gas +import mekanism.api.chemical.gas.GasStack +import net.minecraftforge.registries.ForgeRegistry + +import scala.collection.convert.ImplicitConversionsToScala._ + +object ConverterGasStack extends api.driver.Converter { + override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]) = + value match { + case stack: GasStack => + if (Settings.get.insertIdsInConverters) { + output += "id" -> Int.box(MekanismAPI.gasRegistry().asInstanceOf[ForgeRegistry[Gas]].getID(stack.getType)) + } + output += "amount" -> Long.box(stack.getAmount) + val gas = stack.getType + if (gas != null) { + output += "name" -> gas.getRegistryName.toString + output += "label" -> gas.getTextComponent.getString + } + case _ => + } +} diff --git a/src/main/scala/li/cil/oc/integration/mekanism/EventHandlerMekanism.scala b/src/main/scala/li/cil/oc/integration/mekanism/EventHandlerMekanism.scala deleted file mode 100644 index b15ec865fd..0000000000 --- a/src/main/scala/li/cil/oc/integration/mekanism/EventHandlerMekanism.scala +++ /dev/null @@ -1,18 +0,0 @@ -package li.cil.oc.integration.mekanism - -import mekanism.api.IMekWrench -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.item.ItemStack -import net.minecraft.util.EnumHand -import net.minecraft.util.math.BlockPos - -object EventHandlerMekanism { - def useWrench(player: EntityPlayer, pos: BlockPos, changeDurability: Boolean): Boolean = { - player.getHeldItem(EnumHand.MAIN_HAND).getItem match { - case wrench: IMekWrench => wrench.canUseWrench(player.getHeldItem(EnumHand.MAIN_HAND), player, pos) - case _ => false - } - } - - def isWrench(stack: ItemStack): Boolean = stack.getItem.isInstanceOf[IMekWrench] -} diff --git a/src/main/scala/li/cil/oc/integration/mekanism/ModMekanism.scala b/src/main/scala/li/cil/oc/integration/mekanism/ModMekanism.scala index fd312da907..1da9310e9e 100644 --- a/src/main/scala/li/cil/oc/integration/mekanism/ModMekanism.scala +++ b/src/main/scala/li/cil/oc/integration/mekanism/ModMekanism.scala @@ -8,7 +8,6 @@ object ModMekanism extends ModProxy { override def getMod = Mods.Mekanism override def initialize(): Unit = { - api.IMC.registerWrenchTool("li.cil.oc.integration.mekanism.EventHandlerMekanism.useWrench") - api.IMC.registerWrenchToolCheck("li.cil.oc.integration.mekanism.EventHandlerMekanism.isWrench") + api.Driver.add(ConverterGasStack) } } diff --git a/src/main/scala/li/cil/oc/integration/mekanism/gas/ConverterGasStack.scala b/src/main/scala/li/cil/oc/integration/mekanism/gas/ConverterGasStack.scala deleted file mode 100644 index dd7a1e0561..0000000000 --- a/src/main/scala/li/cil/oc/integration/mekanism/gas/ConverterGasStack.scala +++ /dev/null @@ -1,25 +0,0 @@ -package li.cil.oc.integration.mekanism.gas - -import java.util - -import li.cil.oc.Settings -import li.cil.oc.api - -import scala.collection.convert.WrapAsScala._ - -object ConverterGasStack extends api.driver.Converter { - override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]) = - value match { - case stack: mekanism.api.gas.GasStack => - if (Settings.get.insertIdsInConverters) { - output += "id" -> Int.box(stack.getGas.getID) - } - output += "amount" -> Int.box(stack.amount) - val gas = stack.getGas - if (gas != null) { - output += "name" -> gas.getName - output += "label" -> gas.getLocalizedName - } - case _ => - } -} diff --git a/src/main/scala/li/cil/oc/integration/mekanism/gas/ModMekanismGas.scala b/src/main/scala/li/cil/oc/integration/mekanism/gas/ModMekanismGas.scala deleted file mode 100644 index ec52e082ba..0000000000 --- a/src/main/scala/li/cil/oc/integration/mekanism/gas/ModMekanismGas.scala +++ /dev/null @@ -1,14 +0,0 @@ -package li.cil.oc.integration.mekanism.gas - -import li.cil.oc.api.Driver -import li.cil.oc.integration.Mod -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods - -object ModMekanismGas extends ModProxy { - override def getMod: Mod = Mods.MekanismGas - - override def initialize(): Unit = { - Driver.add(ConverterGasStack) - } -} diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidStack.scala b/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidStack.scala index f46fa0cb1e..069dc44e51 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidStack.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidStack.scala @@ -4,19 +4,17 @@ import java.util import li.cil.oc.api -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ConverterFluidStack extends api.driver.Converter { override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]) = value match { case stack: net.minecraftforge.fluids.FluidStack => - output += "amount" -> Int.box(stack.amount) - output += "hasTag" -> Boolean.box(stack.tag != null) + output += "amount" -> Int.box(stack.getAmount) + output += "hasTag" -> Boolean.box(stack.hasTag) val fluid = stack.getFluid - if (fluid != null) { - output += "name" -> fluid.getName - output += "label" -> fluid.getLocalizedName(stack) - } + output += "name" -> fluid.getRegistryName.toString + output += "label" -> fluid.getAttributes.getDisplayName(stack).getString case _ => } } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankInfo.scala b/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankInfo.scala index 7e36d439a6..c0e312daf5 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankInfo.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankInfo.scala @@ -5,15 +5,15 @@ import java.util import li.cil.oc.api import net.minecraftforge.fluids -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ConverterFluidTankInfo extends api.driver.Converter { override def convert(value: AnyRef, output: util.Map[AnyRef, AnyRef]) = value match { - case tankInfo: fluids.FluidTankInfo => - output += "capacity" -> Int.box(tankInfo.capacity) - if (tankInfo.fluid != null) { - ConverterFluidStack.convert(tankInfo.fluid, output) + case tankInfo: fluids.IFluidTank => + output += "capacity" -> Int.box(tankInfo.getCapacity) + if (!tankInfo.getFluid.isEmpty) { + ConverterFluidStack.convert(tankInfo.getFluid, output) } else output += "amount" -> Int.box(0) case _ => diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankProperties.scala b/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankProperties.scala index 80c99189df..3c7c80cd77 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankProperties.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/ConverterFluidTankProperties.scala @@ -3,16 +3,16 @@ package li.cil.oc.integration.minecraft import java.util import li.cil.oc.api -import net.minecraftforge.fluids +import li.cil.oc.util.ExtendedArguments.TankProperties -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ConverterFluidTankProperties extends api.driver.Converter { override def convert(value: AnyRef, output: util.Map[AnyRef, AnyRef]) = value match { - case properties: fluids.capability.IFluidTankProperties => - output += "capacity" -> Int.box(properties.getCapacity) - val fluid = properties.getContents + case properties: TankProperties => + output += "capacity" -> Int.box(properties.capacity) + val fluid = properties.contents if (fluid != null) { ConverterFluidStack.convert(fluid, output) } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ConverterItemStack.scala b/src/main/scala/li/cil/oc/integration/minecraft/ConverterItemStack.scala index e7a1efeba3..f8e263e1c7 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/ConverterItemStack.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/ConverterItemStack.scala @@ -5,31 +5,30 @@ import java.util import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.integration.Mods -import net.minecraftforge.fml.common.Loader import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.enchantment.EnchantmentHelper import li.cil.oc.util.ItemUtils +import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.item import net.minecraft.item.Item -import net.minecraft.nbt.{NBTTagCompound, NBTTagList, NBTTagString} +import net.minecraft.nbt.{CompoundNBT, ListNBT, StringNBT} +import net.minecraft.tags.ItemTags import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.oredict.OreDictionary -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object ConverterItemStack extends api.driver.Converter { - def getTagValue(tag: NBTTagCompound, key: String): AnyRef = tag.getTagId(key) match { - case NBT.TAG_INT => Int.box(tag.getInteger(key)) + def getTagValue(tag: CompoundNBT, key: String): AnyRef = tag.getTagType(key) match { + case NBT.TAG_INT => Int.box(tag.getInt(key)) case NBT.TAG_STRING => tag.getString(key) case NBT.TAG_BYTE => Byte.box(tag.getByte(key)) - case NBT.TAG_COMPOUND => tag.getCompoundTag(key) - case NBT.TAG_LIST => tag.getTagList(key, NBT.TAG_STRING) + case NBT.TAG_COMPOUND => tag.getCompound(key) + case NBT.TAG_LIST => tag.getList(key, NBT.TAG_STRING) case _ => null } - def withTag(tag: NBTTagCompound, key: String, tagId: Int, f: AnyRef => AnyRef): AnyRef = { - if (tag.hasKey(key, tagId)) { + def withTag(tag: CompoundNBT, key: String, tagId: Int, f: AnyRef => AnyRef): AnyRef = { + if (tag.contains(key, tagId)) { Option(getTagValue(tag, key)) match { case Some(value) => f(value) case _ => null @@ -37,60 +36,43 @@ object ConverterItemStack extends api.driver.Converter { } else null } - def withCompound(tag: NBTTagCompound, key: String, f: NBTTagCompound => AnyRef): AnyRef = { - withTag(tag, key, NBT.TAG_COMPOUND, { case value: NBTTagCompound => f(value)}) + def withCompound(tag: CompoundNBT, key: String, f: CompoundNBT => AnyRef): AnyRef = { + withTag(tag, key, NBT.TAG_COMPOUND, { case value: CompoundNBT => f(value)}) } - def withList(tag: NBTTagCompound, key: String, f: NBTTagList => AnyRef): AnyRef = { - withTag(tag, key, NBT.TAG_STRING, { case value: NBTTagList => f(value)}) + def withList(tag: CompoundNBT, key: String, f: ListNBT => AnyRef): AnyRef = { + withTag(tag, key, NBT.TAG_STRING, { case value: ListNBT => f(value)}) } override def convert(value: AnyRef, output: util.Map[AnyRef, AnyRef]) = value match { case stack: item.ItemStack => if (Settings.get.insertIdsInConverters) { - output += "id" -> Int.box(Item.getIdFromItem(stack.getItem)) - output += "oreNames" -> OreDictionary.getOreIDs(stack).map(OreDictionary.getOreName) + output += "id" -> Int.box(Item.getId(stack.getItem)) + output += "oreNames" -> stack.getItem.getTags.map(_.toString).toArray } - output += "damage" -> Int.box(stack.getItemDamage) + output += "damage" -> Int.box(stack.getDamageValue) output += "maxDamage" -> Int.box(stack.getMaxDamage) output += "size" -> Int.box(stack.getCount) output += "maxSize" -> Int.box(stack.getMaxStackSize) - output += "hasTag" -> Boolean.box(stack.hasTagCompound) - output += "name" -> Item.REGISTRY.getNameForObject(stack.getItem) - output += "label" -> stack.getDisplayName + output += "hasTag" -> Boolean.box(stack.hasTag) + output += "name" -> stack.getItem.getRegistryName + output += "label" -> stack.getDisplayName.getString // custom mod tags - if (stack.hasTagCompound) { - val tags = stack.getTagCompound + if (stack.hasTag) { + val tags = stack.getTag //Lore tags withCompound(tags, "display", withList(_, "Lore", { - output += "lore" -> _.map((tag: NBTTagString) => tag.getString).mkString("\n") + output += "lore" -> _.map((tag: StringNBT) => tag.getAsString).mkString("\n") }) ) - // IC2 reactor items custom damage - withTag(tags, "advDmg", NBT.TAG_INT, dmg => output += "customDamage" -> dmg) - - // draconic upgrades - if (Mods.DraconicEvolution.isModAvailable) { - withCompound(tags, "DEUpgrades", de => { - output += "DEUpgrades" -> de - }) - (0 until 15).foreach(n => { - val profileName: String = s"Profile_$n" - Option(getTagValue(tags, profileName)) match { - case Some(profile: NBTTagCompound) => output += profileName -> profile - case _ => - } - }) - } - withTag(tags, "Energy", NBT.TAG_INT, value => output += "Energy" -> value) if (Settings.get.allowItemStackNBTTags) { - output += "tag" -> ItemUtils.saveTag(stack.getTagCompound) + output += "tag" -> ItemUtils.saveTag(stack.getTag) } } @@ -98,8 +80,8 @@ object ConverterItemStack extends api.driver.Converter { EnchantmentHelper.getEnchantments(stack).collect { case (enchantment, level) => val map = mutable.Map[String, Any]( - "name" -> enchantment.getName, - "label" -> enchantment.getTranslatedName(level), + "name" -> enchantment.getRegistryName, + "label" -> enchantment.getFullname(level), "level" -> level ) enchantments += map diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ConverterNBT.scala b/src/main/scala/li/cil/oc/integration/minecraft/ConverterNBT.scala index d664f4932c..e4d162fe0e 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/ConverterNBT.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/ConverterNBT.scala @@ -5,31 +5,31 @@ import java.util import li.cil.oc.api import net.minecraft.nbt._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ConverterNBT extends api.driver.Converter { override def convert(value: AnyRef, output: util.Map[AnyRef, AnyRef]) = value match { - case nbt: NBTTagCompound => output += "oc:flatten" -> convert(nbt) + case nbt: CompoundNBT => output += "oc:flatten" -> convert(nbt) case _ => } - private def convert(nbt: NBTBase): AnyRef = nbt match { - case tag: NBTTagByte => Byte.box(tag.getByte) - case tag: NBTTagShort => Short.box(tag.getShort) - case tag: NBTTagInt => Int.box(tag.getInt) - case tag: NBTTagLong => Long.box(tag.getLong) - case tag: NBTTagFloat => Float.box(tag.getFloat) - case tag: NBTTagDouble => Double.box(tag.getDouble) - case tag: NBTTagByteArray => tag.getByteArray - case tag: NBTTagString => tag.getString - case tag: NBTTagList => - val copy = tag.copy(): NBTTagList - (0 until copy.tagCount).map(_ => convert(copy.removeTag(0))).toArray - case tag: NBTTagCompound => - tag.getKeySet.collect { - case key: String => key -> convert(tag.getTag(key)) + private def convert(nbt: INBT): AnyRef = nbt match { + case tag: ByteNBT => Byte.box(tag.getAsByte) + case tag: ShortNBT => Short.box(tag.getAsShort) + case tag: IntNBT => Int.box(tag.getAsInt) + case tag: LongNBT => Long.box(tag.getAsLong) + case tag: FloatNBT => Float.box(tag.getAsFloat) + case tag: DoubleNBT => Double.box(tag.getAsDouble) + case tag: ByteArrayNBT => tag.getAsByteArray + case tag: StringNBT => tag.getAsString + case tag: ListNBT => + val copy = tag.copy(): ListNBT + (0 until copy.size).map(_ => convert(copy.remove(0))).toArray + case tag: CompoundNBT => + tag.getAllKeys.collect { + case key: String => key -> convert(tag.get(key)) }.toMap - case tag: NBTTagIntArray => tag.getIntArray + case tag: IntArrayNBT => tag.getAsIntArray } } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ConverterWorld.scala b/src/main/scala/li/cil/oc/integration/minecraft/ConverterWorld.scala index c8d6d889ec..5c75574987 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/ConverterWorld.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/ConverterWorld.scala @@ -1,17 +1,31 @@ package li.cil.oc.integration.minecraft +import java.nio.charset.StandardCharsets import java.util +import java.util.UUID +import com.google.common.hash.Hashing import li.cil.oc.api -import net.minecraft.world +import net.minecraft.world.World +import net.minecraft.world.server.ServerWorld -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ConverterWorld extends api.driver.Converter { - override def convert(value: AnyRef, output: util.Map[AnyRef, AnyRef]) = + override def convert(value: AnyRef, output: util.Map[AnyRef, AnyRef]) = { value match { - case world: world.World => - output += "oc:flatten" -> world.provider + case world: ServerWorld => + output += "id" -> UUID.nameUUIDFromBytes(Hashing.md5().newHasher(). + putLong(world.getSeed). + putString(world.dimension.location.toString, StandardCharsets.UTF_8). + hash().asBytes()).toString case _ => } + + value match { + case world: World => + output += "name" -> world.dimension.location.toString + case _ => + } + } } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ConverterWorldProvider.scala b/src/main/scala/li/cil/oc/integration/minecraft/ConverterWorldProvider.scala deleted file mode 100644 index 93ee7c9b64..0000000000 --- a/src/main/scala/li/cil/oc/integration/minecraft/ConverterWorldProvider.scala +++ /dev/null @@ -1,23 +0,0 @@ -package li.cil.oc.integration.minecraft - -import java.util -import java.util.UUID - -import com.google.common.hash.Hashing -import li.cil.oc.api -import net.minecraft.world - -import scala.collection.convert.WrapAsScala._ - -object ConverterWorldProvider extends api.driver.Converter { - override def convert(value: AnyRef, output: util.Map[AnyRef, AnyRef]) = - value match { - case provider: world.WorldProvider => - output += "id" -> UUID.nameUUIDFromBytes(Hashing.md5().newHasher(). - putLong(provider.getSeed). - putInt(provider.getDimension). - hash().asBytes()).toString - output += "name" -> provider.getDimensionType.getName - case _ => - } -} diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverBeacon.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverBeacon.scala index 5f8ae6edc5..5d3a1bd735 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverBeacon.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverBeacon.scala @@ -10,51 +10,48 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ResultWrapper.result import net.minecraft.block.Block -import net.minecraft.init.Blocks +import net.minecraft.block.Blocks import net.minecraft.item.ItemStack -import net.minecraft.potion.Potion -import net.minecraft.tileentity.TileEntityBeacon -import net.minecraft.util.EnumFacing +import net.minecraft.potion.Effect +import net.minecraft.tileentity.BeaconTileEntity +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverBeacon extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[TileEntityBeacon] + override def getTileEntityClass: Class[_] = classOf[BeaconTileEntity] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntityBeacon]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[BeaconTileEntity]) - final class Environment(tileEntity: TileEntityBeacon) extends ManagedTileEntityEnvironment[TileEntityBeacon](tileEntity, "beacon") with NamedBlock { + final class Environment(tileEntity: BeaconTileEntity) extends ManagedTileEntityEnvironment[BeaconTileEntity](tileEntity, "beacon") with NamedBlock { override def preferredName = "beacon" override def priority = 0 @Callback(doc = "function():number -- Get the number of levels for this beacon.") def getLevels(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getField(0)) + result(tileEntity.getLevels) } @Callback(doc = "function():string -- Get the name of the active primary effect.") def getPrimaryEffect(context: Context, args: Arguments): Array[AnyRef] = { - result(getEffectName(tileEntity.getField(1))) + result(getEffectName(tileEntity.primaryPower)) } @Callback(doc = "function():string -- Get the name of the active secondary effect.") def getSecondaryEffect(context: Context, args: Arguments): Array[AnyRef] = { - result(getEffectName(tileEntity.getField(2))) + result(getEffectName(tileEntity.secondaryPower)) } - private def getEffectName(id: Int): String = { - val potion = Potion.getPotionById(id) - if (potion != null) - Potion.getPotionById(id).getName - else null + private def getEffectName(effect: Effect): String = { + if (effect != null) effect.getRegistryName.toString else null } } object Provider extends EnvironmentProvider { override def getEnvironment(stack: ItemStack): Class[_] = { - if (!stack.isEmpty && Block.getBlockFromItem(stack.getItem) == Blocks.BEACON) + if (!stack.isEmpty && Block.byItem(stack.getItem) == Blocks.BEACON) classOf[Environment] else null } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverBrewingStand.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverBrewingStand.scala index f46a7456bf..3d80e521f6 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverBrewingStand.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverBrewingStand.scala @@ -9,27 +9,27 @@ import li.cil.oc.api.network.ManagedEnvironment import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ResultWrapper.result -import net.minecraft.init.Items +import net.minecraft.item.Items import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntityBrewingStand -import net.minecraft.util.EnumFacing +import net.minecraft.tileentity.BrewingStandTileEntity +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverBrewingStand extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[TileEntityBrewingStand] + override def getTileEntityClass: Class[_] = classOf[BrewingStandTileEntity] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntityBrewingStand]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[BrewingStandTileEntity]) - final class Environment(tileEntity: TileEntityBrewingStand) extends ManagedTileEntityEnvironment[TileEntityBrewingStand](tileEntity, "brewing_stand") with NamedBlock { + final class Environment(tileEntity: BrewingStandTileEntity) extends ManagedTileEntityEnvironment[BrewingStandTileEntity](tileEntity, "brewing_stand") with NamedBlock { override def preferredName = "brewing_stand" override def priority = 0 @Callback(doc = "function():number -- Get the number of ticks remaining of the current brewing operation.") def getBrewTime(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getField(0)) + result(tileEntity.brewTime) } } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverCommandBlock.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverCommandBlock.scala index 7c6f55fb92..b68de56a1d 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverCommandBlock.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverCommandBlock.scala @@ -10,53 +10,53 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ResultWrapper.result import net.minecraft.block.Block -import net.minecraft.init.Blocks +import net.minecraft.block.Blocks import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntityCommandBlock -import net.minecraft.util.EnumFacing +import net.minecraft.tileentity.CommandBlockTileEntity +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import net.minecraftforge.fml.common.FMLCommonHandler +import net.minecraftforge.fml.server.ServerLifecycleHooks object DriverCommandBlock extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[TileEntityCommandBlock] + override def getTileEntityClass: Class[_] = classOf[CommandBlockTileEntity] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntityCommandBlock]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[CommandBlockTileEntity]) - final class Environment(tileEntity: TileEntityCommandBlock) extends ManagedTileEntityEnvironment[TileEntityCommandBlock](tileEntity, "command_block") with NamedBlock { + final class Environment(tileEntity: CommandBlockTileEntity) extends ManagedTileEntityEnvironment[CommandBlockTileEntity](tileEntity, "command_block") with NamedBlock { override def preferredName = "command_block" override def priority = 0 @Callback(direct = true, doc = "function():string -- Get the command currently set in this command block.") def getCommand(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getCommandBlockLogic.getCommand) + result(tileEntity.getCommandBlock.getCommand) } @Callback(doc = "function(value:string) -- Set the specified command for the command block.") def setCommand(context: Context, args: Arguments): Array[AnyRef] = { - tileEntity.getCommandBlockLogic.setCommand(args.checkString(0)) - tileEntity.getWorld.notifyBlockUpdate(tileEntity.getPos, tileEntity.getWorld.getBlockState(tileEntity.getPos), tileEntity.getWorld.getBlockState(tileEntity.getPos), 3) + tileEntity.getCommandBlock.setCommand(args.checkString(0)) + tileEntity.getLevel.sendBlockUpdated(tileEntity.getBlockPos, tileEntity.getLevel.getBlockState(tileEntity.getBlockPos), tileEntity.getLevel.getBlockState(tileEntity.getBlockPos), 3) result(true) } @Callback(doc = "function():number -- Execute the currently set command. This has a slight delay to allow the command block to properly update.") def executeCommand(context: Context, args: Arguments): Array[AnyRef] = { context.pause(0.1) - if (!FMLCommonHandler.instance.getMinecraftServerInstance.isCommandBlockEnabled) { + if (!ServerLifecycleHooks.getCurrentServer.isCommandBlockEnabled) { result(null, "command blocks are disabled") } else { - val commandSender = tileEntity.getCommandBlockLogic - commandSender.trigger(tileEntity.getWorld) - result(commandSender.getSuccessCount, commandSender.getLastOutput.getUnformattedText) + val commandSender = tileEntity.getCommandBlock + commandSender.performCommand(tileEntity.getLevel) + result(commandSender.getSuccessCount, commandSender.getLastOutput.getString) } } } object Provider extends EnvironmentProvider { override def getEnvironment(stack: ItemStack): Class[_] = { - if (!stack.isEmpty && Block.getBlockFromItem(stack.getItem) == Blocks.COMMAND_BLOCK) + if (!stack.isEmpty && Block.byItem(stack.getItem) == Blocks.COMMAND_BLOCK) classOf[Environment] else null } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverComparator.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverComparator.scala index a7ea2143ed..6e89d9f7fd 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverComparator.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverComparator.scala @@ -9,20 +9,20 @@ import li.cil.oc.api.network.ManagedEnvironment import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ResultWrapper.result -import net.minecraft.init.Items +import net.minecraft.item.Items import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntityComparator -import net.minecraft.util.EnumFacing +import net.minecraft.tileentity.ComparatorTileEntity +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverComparator extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[TileEntityComparator] + override def getTileEntityClass: Class[_] = classOf[ComparatorTileEntity] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntityComparator]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[ComparatorTileEntity]) - final class Environment(tileEntity: TileEntityComparator) extends ManagedTileEntityEnvironment[TileEntityComparator](tileEntity, "comparator") with NamedBlock { + final class Environment(tileEntity: ComparatorTileEntity) extends ManagedTileEntityEnvironment[ComparatorTileEntity](tileEntity, "comparator") with NamedBlock { override def preferredName = "comparator" override def priority = 0 diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidHandler.java b/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidHandler.java index 505ac64a5c..5f2777106d 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidHandler.java +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidHandler.java @@ -6,8 +6,9 @@ import li.cil.oc.api.machine.Context; import li.cil.oc.api.network.ManagedEnvironment; import li.cil.oc.integration.ManagedTileEntityEnvironment; +import li.cil.oc.util.ExtendedArguments.TankProperties; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; @@ -15,18 +16,17 @@ public final class DriverFluidHandler implements DriverBlock { @Override - public boolean worksWith(final World world, final BlockPos pos, final EnumFacing side) { - final TileEntity tileEntity = world.getTileEntity(pos); + public boolean worksWith(final World world, final BlockPos pos, final Direction side) { + final TileEntity tileEntity = world.getBlockEntity(pos); if (tileEntity == null) { return false; } - return tileEntity.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side) && - tileEntity.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side) != null; + return tileEntity.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side).isPresent(); } @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment(world.getTileEntity(pos).getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side)); + public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final Direction side) { + return new Environment(world.getBlockEntity(pos).getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side).orElse(null)); } public static final class Environment extends ManagedTileEntityEnvironment { @@ -36,7 +36,11 @@ public Environment(final IFluidHandler tileEntity) { @Callback(doc = "function():table -- Get some information about the tank accessible from the specified side.") public Object[] getTankInfo(final Context context, final Arguments args) { - return tileEntity.getTankProperties(); + TankProperties[] props = new TankProperties[tileEntity.getTanks()]; + for (int i = 0; i < props.length; i++) { + props[i] = new TankProperties(tileEntity.getTankCapacity(i), tileEntity.getFluidInTank(i)); + } + return props; } } } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidTank.java b/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidTank.java index d319492e1d..3fefc5fc70 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidTank.java +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverFluidTank.java @@ -6,8 +6,9 @@ import li.cil.oc.api.network.ManagedEnvironment; import li.cil.oc.api.prefab.DriverSidedTileEntity; import li.cil.oc.integration.ManagedTileEntityEnvironment; +import li.cil.oc.util.ExtendedArguments.TankProperties; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.EnumFacing; +import net.minecraft.util.Direction; import net.minecraft.world.World; import net.minecraftforge.fluids.IFluidTank; @@ -18,8 +19,8 @@ public Class getTileEntityClass() { } @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment((IFluidTank) world.getTileEntity(pos)); + public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final Direction side) { + return new Environment((IFluidTank) world.getBlockEntity(pos)); } public static final class Environment extends ManagedTileEntityEnvironment { @@ -29,7 +30,7 @@ public Environment(final IFluidTank tileEntity) { @Callback(doc = "function():table -- Get some information about this tank.") public Object[] getInfo(final Context context, final Arguments args) { - return new Object[]{tileEntity.getInfo()}; + return new Object[]{new TankProperties(tileEntity.getCapacity(), tileEntity.getFluid())}; } } } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverFurnace.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverFurnace.scala index 90b7e51e1a..e7f8cba296 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverFurnace.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverFurnace.scala @@ -10,53 +10,53 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ResultWrapper.result import net.minecraft.block.Block -import net.minecraft.init.Blocks +import net.minecraft.block.Blocks import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntityFurnace -import net.minecraft.util.EnumFacing +import net.minecraft.tileentity.FurnaceTileEntity +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverFurnace extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[TileEntityFurnace] + override def getTileEntityClass: Class[_] = classOf[FurnaceTileEntity] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntityFurnace]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[FurnaceTileEntity]) - final class Environment(tileEntity: TileEntityFurnace) extends ManagedTileEntityEnvironment[TileEntityFurnace](tileEntity, "furnace") with NamedBlock { + final class Environment(tileEntity: FurnaceTileEntity) extends ManagedTileEntityEnvironment[FurnaceTileEntity](tileEntity, "furnace") with NamedBlock { override def preferredName = "furnace" override def priority = 0 @Callback(doc = "function():number -- The number of ticks that the furnace will keep burning from the last consumed fuel.") def getBurnTime(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getField(0)) + result(tileEntity.litTime) } @Callback(doc = "function():number -- The number of ticks that the currently burning fuel lasts in total.") def getCurrentItemBurnTime(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getField(1)) + result(tileEntity.litDuration) } @Callback(doc = "function():number -- The number of ticks that the current item has been cooking for.") def getCookTime(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getField(2)) + result(tileEntity.cookingProgress) } @Callback(doc = "function():number -- The number of ticks that the current item needs to cook.") def getTotalCookTime(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getField(3)) + result(tileEntity.cookingTotalTime) } @Callback(doc = "function():boolean -- Get whether the furnace is currently active.") def isBurning(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.isBurning) + result(tileEntity.litTime > 0) } } object Provider extends EnvironmentProvider { override def getEnvironment(stack: ItemStack): Class[_] = { - if (!stack.isEmpty && Block.getBlockFromItem(stack.getItem) == Blocks.FURNACE) + if (!stack.isEmpty && Block.byItem(stack.getItem) == Blocks.FURNACE) classOf[Environment] else null } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverInventory.java b/src/main/scala/li/cil/oc/integration/minecraft/DriverInventory.java index 566f2a9c85..677dddeaf9 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverInventory.java +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverInventory.java @@ -8,19 +8,21 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity; import li.cil.oc.integration.ManagedTileEntityEnvironment; import li.cil.oc.util.BlockPosition; -import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.INameable; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; +import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.util.FakePlayerFactory; import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.fml.common.eventhandler.Event; +import net.minecraftforge.eventbus.api.Event; public final class DriverInventory extends DriverSidedTileEntity { @Override @@ -29,37 +31,38 @@ public Class getTileEntityClass() { } @Override - public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final EnumFacing side) { - return new Environment(world.getTileEntity(pos), world); + public ManagedEnvironment createEnvironment(final World world, final BlockPos pos, final Direction side) { + return new Environment(world.getBlockEntity(pos), world); } public static final class Environment extends ManagedTileEntityEnvironment { - private final EntityPlayer fakePlayer; + private final PlayerEntity fakePlayer; private final BlockPosition position; public Environment(final TileEntity tileEntity, final World world) { super((IInventory) tileEntity, "inventory"); - fakePlayer = FakePlayerFactory.get((WorldServer) world, Settings.get().fakePlayerProfile()); - position = BlockPosition.apply(tileEntity.getPos(), world); + fakePlayer = FakePlayerFactory.get((ServerWorld) world, Settings.get().fakePlayerProfile()); + position = BlockPosition.apply(tileEntity.getBlockPos(), world); } @Callback(doc = "function():string -- Get the name of this inventory.") public Object[] getInventoryName(final Context context, final Arguments args) { if (notPermitted()) return new Object[]{null, "permission denied"}; - return new Object[]{tileEntity.getName()}; + if (tileEntity instanceof INameable) return new Object[]{((INameable) tileEntity).getName().getString()}; + return new Object[]{null, "inventory is unnamed"}; } @Callback(doc = "function():number -- Get the number of slots in this inventory.") public Object[] getInventorySize(final Context context, final Arguments args) { if (notPermitted()) return new Object[]{null, "permission denied"}; - return new Object[]{tileEntity.getSizeInventory()}; + return new Object[]{tileEntity.getContainerSize()}; } @Callback(doc = "function(slot:number):number -- Get the stack size of the item stack in the specified slot.") public Object[] getSlotStackSize(final Context context, final Arguments args) { if (notPermitted()) return new Object[]{null, "permission denied"}; final int slot = checkSlot(args, 0); - final ItemStack stack = tileEntity.getStackInSlot(slot); + final ItemStack stack = tileEntity.getItem(slot); if (!stack.isEmpty()) { return new Object[]{stack.getCount()}; } else { @@ -71,11 +74,11 @@ public Object[] getSlotStackSize(final Context context, final Arguments args) { public Object[] getSlotMaxStackSize(final Context context, final Arguments args) { if (notPermitted()) return new Object[]{null, "permission denied"}; final int slot = checkSlot(args, 0); - final ItemStack stack = tileEntity.getStackInSlot(slot); + final ItemStack stack = tileEntity.getItem(slot); if (!stack.isEmpty()) { - return new Object[]{Math.min(tileEntity.getInventoryStackLimit(), stack.getMaxStackSize())}; + return new Object[]{Math.min(tileEntity.getMaxStackSize(), stack.getMaxStackSize())}; } else { - return new Object[]{tileEntity.getInventoryStackLimit()}; + return new Object[]{tileEntity.getMaxStackSize()}; } } @@ -87,8 +90,8 @@ public Object[] compareStacks(final Context context, final Arguments args) { if (slotA == slotB) { return new Object[]{true}; } - final ItemStack stackA = tileEntity.getStackInSlot(slotA); - final ItemStack stackB = tileEntity.getStackInSlot(slotB); + final ItemStack stackA = tileEntity.getItem(slotA); + final ItemStack stackB = tileEntity.getItem(slotB); if (stackA.isEmpty() && stackB.isEmpty()) { return new Object[]{true}; } else if (!stackA.isEmpty() && !stackB.isEmpty()) { @@ -103,37 +106,37 @@ public Object[] transferStack(final Context context, final Arguments args) { if (notPermitted()) return new Object[]{null, "permission denied"}; final int slotA = checkSlot(args, 0); final int slotB = checkSlot(args, 1); - final int count = Math.max(0, Math.min(args.count() > 2 && args.checkAny(2) != null ? args.checkInteger(2) : 64, tileEntity.getInventoryStackLimit())); + final int count = Math.max(0, Math.min(args.count() > 2 && args.checkAny(2) != null ? args.checkInteger(2) : 64, tileEntity.getMaxStackSize())); if (slotA == slotB || count == 0) { return new Object[]{true}; } - final ItemStack stackA = tileEntity.getStackInSlot(slotA); - final ItemStack stackB = tileEntity.getStackInSlot(slotB); + final ItemStack stackA = tileEntity.getItem(slotA); + final ItemStack stackB = tileEntity.getItem(slotB); if (stackA.isEmpty()) { // Empty. return new Object[]{false}; } else if (stackB.isEmpty()) { // Move. - tileEntity.setInventorySlotContents(slotB, tileEntity.decrStackSize(slotA, count)); + tileEntity.setItem(slotB, tileEntity.removeItem(slotA, count)); return new Object[]{true}; } else if (itemEquals(stackA, stackB)) { // Pile. - final int space = Math.min(tileEntity.getInventoryStackLimit(), stackB.getMaxStackSize()) - stackB.getCount(); + final int space = Math.min(tileEntity.getMaxStackSize(), stackB.getMaxStackSize()) - stackB.getCount(); final int amount = Math.min(count, Math.min(space, stackA.getCount())); if (amount > 0) { // Some. stackA.setCount(stackA.getCount() - amount); stackB.setCount(stackB.getCount() + amount); if (stackA.getCount() == 0) { - tileEntity.setInventorySlotContents(slotA, ItemStack.EMPTY); + tileEntity.setItem(slotA, ItemStack.EMPTY); } - tileEntity.markDirty(); + tileEntity.setChanged(); return new Object[]{true}; } } else if (count >= stackA.getCount()) { // Swap. - tileEntity.setInventorySlotContents(slotB, stackA); - tileEntity.setInventorySlotContents(slotA, stackB); + tileEntity.setItem(slotB, stackA); + tileEntity.setItem(slotA, stackB); return new Object[]{true}; } // Fail. @@ -141,10 +144,10 @@ public Object[] transferStack(final Context context, final Arguments args) { } @Callback(doc = "function(slot:number):table -- Get a description of the item stack in the specified slot.") - public Object[] getStackInSlot(final Context context, final Arguments args) { + public Object[] getItem(final Context context, final Arguments args) { if (Settings.get().allowItemStackInspection()) { if (notPermitted()) return new Object[]{null, "permission denied"}; - return new Object[]{tileEntity.getStackInSlot(checkSlot(args, 0))}; + return new Object[]{tileEntity.getItem(checkSlot(args, 0))}; } else { return new Object[]{null, "not enabled in config"}; } @@ -154,9 +157,9 @@ public Object[] getStackInSlot(final Context context, final Arguments args) { public Object[] getAllStacks(final Context context, final Arguments args) { if (Settings.get().allowItemStackInspection()) { if (notPermitted()) return new Object[]{null, "permission denied"}; - ItemStack[] allStacks = new ItemStack[tileEntity.getSizeInventory()]; - for (int i = 0; i < tileEntity.getSizeInventory(); i++) { - allStacks[i] = tileEntity.getStackInSlot(i); + ItemStack[] allStacks = new ItemStack[tileEntity.getContainerSize()]; + for (int i = 0; i < tileEntity.getContainerSize(); i++) { + allStacks[i] = tileEntity.getItem(i); } return new Object[]{allStacks}; } else { @@ -166,22 +169,23 @@ public Object[] getAllStacks(final Context context, final Arguments args) { private int checkSlot(final Arguments args, final int number) { final int slot = args.checkInteger(number) - 1; - if (slot < 0 || slot >= tileEntity.getSizeInventory()) { + if (slot < 0 || slot >= tileEntity.getContainerSize()) { throw new IllegalArgumentException("slot index out of bounds"); } return slot; } private boolean itemEquals(final ItemStack stackA, final ItemStack stackB) { - return stackA.getItem().equals(stackB.getItem()) && !stackA.getHasSubtypes() || stackA.getItemDamage() == stackB.getItemDamage(); + return stackA.getItem().equals(stackB.getItem()) && stackA.getDamageValue() == stackB.getDamageValue(); } private boolean notPermitted() { synchronized (fakePlayer) { - fakePlayer.setPosition(position.toVec3().x, position.toVec3().y, position.toVec3().z); - final PlayerInteractEvent.RightClickBlock event = new PlayerInteractEvent.RightClickBlock(fakePlayer, EnumHand.MAIN_HAND, position.toBlockPos(), EnumFacing.DOWN, null); + fakePlayer.setPos(position.toVec3().x, position.toVec3().y, position.toVec3().z); + final BlockRayTraceResult trace = new BlockRayTraceResult(fakePlayer.position(), Direction.DOWN, position.toBlockPos(), false); + final PlayerInteractEvent.RightClickBlock event = new PlayerInteractEvent.RightClickBlock(fakePlayer, Hand.MAIN_HAND, position.toBlockPos(), trace); MinecraftForge.EVENT_BUS.post(event); - return !event.isCanceled() && event.getUseBlock() != Event.Result.DENY && !tileEntity.isUsableByPlayer(fakePlayer); + return !event.isCanceled() && event.getUseBlock() != Event.Result.DENY && !tileEntity.stillValid(fakePlayer); } } } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverMobSpawner.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverMobSpawner.scala index 17fe50ff17..a4cec231f1 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverMobSpawner.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverMobSpawner.scala @@ -10,33 +10,33 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ResultWrapper.result import net.minecraft.block.Block -import net.minecraft.init.Blocks +import net.minecraft.block.Blocks import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntityMobSpawner -import net.minecraft.util.EnumFacing +import net.minecraft.tileentity.MobSpawnerTileEntity +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverMobSpawner extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[TileEntityMobSpawner] + override def getTileEntityClass: Class[_] = classOf[MobSpawnerTileEntity] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntityMobSpawner]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[MobSpawnerTileEntity]) - final class Environment(tileEntity: TileEntityMobSpawner) extends ManagedTileEntityEnvironment[TileEntityMobSpawner](tileEntity, "mob_spawner") with NamedBlock { + final class Environment(tileEntity: MobSpawnerTileEntity) extends ManagedTileEntityEnvironment[MobSpawnerTileEntity](tileEntity, "mob_spawner") with NamedBlock { override def preferredName = "mob_spawner" override def priority = 0 @Callback(doc = "function():string -- Get the name of the entity that is being spawned by this spawner.") def getSpawningMobName(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.getSpawnerBaseLogic.getEntityId) + result(tileEntity.getSpawner.getEntityId) } } object Provider extends EnvironmentProvider { override def getEnvironment(stack: ItemStack): Class[_] = { - if (!stack.isEmpty && Block.getBlockFromItem(stack.getItem) == Blocks.MOB_SPAWNER) + if (!stack.isEmpty && Block.byItem(stack.getItem) == Blocks.SPAWNER) classOf[Environment] else null } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverNoteBlock.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverNoteBlock.scala index 756cb0c50a..705c2d2ebb 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverNoteBlock.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverNoteBlock.scala @@ -1,37 +1,47 @@ package li.cil.oc.integration.minecraft +import li.cil.oc.api.Network +import li.cil.oc.api.driver.DriverBlock import li.cil.oc.api.driver.EnvironmentProvider import li.cil.oc.api.driver.NamedBlock import li.cil.oc.api.machine.Arguments import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.api.network.ManagedEnvironment -import li.cil.oc.api.prefab.DriverSidedTileEntity -import li.cil.oc.integration.ManagedTileEntityEnvironment +import li.cil.oc.api.network.Visibility +import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.ResultWrapper.result import net.minecraft.block.Block -import net.minecraft.block.material.Material -import net.minecraft.init.Blocks +import net.minecraft.block.Blocks +import net.minecraft.block.NoteBlock import net.minecraft.item.ItemStack -import net.minecraft.tileentity.TileEntityNote -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World -object DriverNoteBlock extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[TileEntityNote] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[TileEntityNote]) +object DriverNoteBlock extends DriverBlock { + override def worksWith(world: World, pos: BlockPos, side: Direction) = world.getBlockState(pos).is(Blocks.NOTE_BLOCK) + + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world, pos) + + final class Environment(val world: World, val pos: BlockPos) extends AbstractManagedEnvironment with NamedBlock { + setNode(Network.newNode(this, Visibility.Network). + withComponent(preferredName). + create()) - final class Environment(tileEntity: TileEntityNote) extends ManagedTileEntityEnvironment[TileEntityNote](tileEntity, "note_block") with NamedBlock { override def preferredName = "note_block" override def priority = 0 @Callback(direct = true, doc = "function():number -- Get the currently set pitch on this note block.") def getPitch(context: Context, args: Arguments): Array[AnyRef] = { - result(tileEntity.note + 1) + val state = world.getBlockState(pos) + if (!state.is(Blocks.NOTE_BLOCK)) { + throw new IllegalArgumentException("block removed") + } + result(state.getValue(NoteBlock.NOTE).intValue + 1) } @Callback(doc = "function(value:number) -- Set the pitch for this note block. Must be in the interval [1, 25].") @@ -45,26 +55,34 @@ object DriverNoteBlock extends DriverSidedTileEntity { if (args.count > 0 && args.checkAny(0) != null) { setPitch(args.checkInteger(0)) } - val world = tileEntity.getWorld - val pos = tileEntity.getPos - val material = world.getBlockState(pos.add(0, 1, 0)).getMaterial - val canTrigger = material == Material.AIR - tileEntity.triggerNote(world, pos) + else { + val state = world.getBlockState(pos) + if (!state.is(Blocks.NOTE_BLOCK)) { + throw new IllegalArgumentException("block removed") + } + } + val canTrigger = world.isEmptyBlock(pos.above) + if (canTrigger) world.blockEvent(pos, Blocks.NOTE_BLOCK, 0, 0) result(canTrigger) } private def setPitch(value: Int): Unit = { - if (value < 1 || value > 25) { + val pitch = Int.box(value - 1) + if (!NoteBlock.NOTE.getPossibleValues.contains(pitch)) { throw new IllegalArgumentException("invalid pitch") } - tileEntity.note = (value - 1).toByte - tileEntity.markDirty() + val state = world.getBlockState(pos) + if (!state.is(Blocks.NOTE_BLOCK)) { + throw new IllegalArgumentException("block removed") + } + val newState = state.setValue(NoteBlock.NOTE, pitch) + if (newState != state) world.setBlock(pos, newState, 3) } } object Provider extends EnvironmentProvider { override def getEnvironment(stack: ItemStack): Class[_] = { - if (!stack.isEmpty && Block.getBlockFromItem(stack.getItem) == Blocks.NOTEBLOCK) + if (!stack.isEmpty && Block.byItem(stack.getItem) == Blocks.NOTE_BLOCK) classOf[Environment] else null } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/DriverRecordPlayer.scala b/src/main/scala/li/cil/oc/integration/minecraft/DriverRecordPlayer.scala index ccb4fd9e8c..ef2d95ff95 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/DriverRecordPlayer.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/DriverRecordPlayer.scala @@ -10,22 +10,23 @@ import li.cil.oc.api.prefab.DriverSidedTileEntity import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ResultWrapper.result import net.minecraft.block.Block -import net.minecraft.block.BlockJukebox -import net.minecraft.init.Blocks +import net.minecraft.block.Blocks import net.minecraft.item.Item -import net.minecraft.item.ItemRecord import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.item.MusicDiscItem +import net.minecraft.tileentity.JukeboxTileEntity +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.LanguageMap import net.minecraft.world.World object DriverRecordPlayer extends DriverSidedTileEntity { - override def getTileEntityClass: Class[_] = classOf[BlockJukebox.TileEntityJukebox] + override def getTileEntityClass: Class[_] = classOf[JukeboxTileEntity] - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(pos).asInstanceOf[BlockJukebox.TileEntityJukebox]) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = + new Environment(world.getBlockEntity(pos).asInstanceOf[JukeboxTileEntity]) - final class Environment(tileEntity: BlockJukebox.TileEntityJukebox) extends ManagedTileEntityEnvironment[BlockJukebox.TileEntityJukebox](tileEntity, "jukebox") with NamedBlock { + final class Environment(tileEntity: JukeboxTileEntity) extends ManagedTileEntityEnvironment[JukeboxTileEntity](tileEntity, "jukebox") with NamedBlock { override def preferredName = "jukebox" override def priority = 0 @@ -33,8 +34,8 @@ object DriverRecordPlayer extends DriverSidedTileEntity { @Callback(doc = "function():string -- Get the title of the record currently in the jukebox.") def getRecord(context: Context, args: Arguments): Array[AnyRef] = { val record = tileEntity.getRecord - if (record != null && record.getItem.isInstanceOf[ItemRecord]) { - result(record.getItem.asInstanceOf[ItemRecord].getRecordNameLocal) + if (!record.isEmpty && record.getItem.isInstanceOf[MusicDiscItem]) { + result(LanguageMap.getInstance.getOrDefault(record.getItem.asInstanceOf[MusicDiscItem].getDescriptionId)) } else null } @@ -42,8 +43,8 @@ object DriverRecordPlayer extends DriverSidedTileEntity { @Callback(doc = "function() -- Start playing the record currently in the jukebox.") def play(context: Context, args: Arguments): Array[AnyRef] = { val record = tileEntity.getRecord - if (record != null && record.getItem.isInstanceOf[ItemRecord]) { - tileEntity.getWorld.playEvent(null, 1005, tileEntity.getPos, Item.getIdFromItem(record.getItem)) + if (!record.isEmpty && record.getItem.isInstanceOf[MusicDiscItem]) { + tileEntity.getLevel.levelEvent(null, 1010, tileEntity.getBlockPos, Item.getId(record.getItem)) result(true) } else null @@ -51,15 +52,14 @@ object DriverRecordPlayer extends DriverSidedTileEntity { @Callback(doc = "function() -- Stop playing the record currently in the jukebox.") def stop(context: Context, args: Arguments): Array[AnyRef] = { - tileEntity.getWorld.playEvent(1005, tileEntity.getPos, 0) - tileEntity.getWorld.playRecord(tileEntity.getPos, null) + tileEntity.getLevel.levelEvent(1010, tileEntity.getBlockPos, 0) null } } object Provider extends EnvironmentProvider { override def getEnvironment(stack: ItemStack): Class[_] = { - if (!stack.isEmpty && Block.getBlockFromItem(stack.getItem) == Blocks.JUKEBOX) + if (stack.getItem == Blocks.JUKEBOX.asItem) classOf[Environment] else null } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/EventHandlerVanilla.scala b/src/main/scala/li/cil/oc/integration/minecraft/EventHandlerVanilla.scala index f20b626cb5..1ca782bbb1 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/EventHandlerVanilla.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/EventHandlerVanilla.scala @@ -5,15 +5,15 @@ import li.cil.oc.api.event.GeolyzerEvent import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ import net.minecraft.block.Block -import net.minecraft.block.BlockCrops -import net.minecraft.block.BlockStem -import net.minecraft.block.properties.PropertyInteger -import net.minecraft.block.state.IBlockState -import net.minecraft.init.Blocks -import net.minecraftforge.fluids.FluidRegistry -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraft.block.CropsBlock +import net.minecraft.block.StemBlock +import net.minecraft.state.IntegerProperty +import net.minecraft.block.BlockState +import net.minecraft.block.Blocks +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fluids.IFluidBlock -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object EventHandlerVanilla { @SubscribeEvent @@ -26,24 +26,20 @@ object EventHandlerVanilla { } val noise = new Array[Byte](e.data.length) - world.rand.nextBytes(noise) + world.random.nextBytes(noise) // Map to [-1, 1). The additional /33f is for normalization below. noise.map(_ / 128f / 33f).copyToArray(e.data) val w = e.maxX - e.minX + 1 val d = e.maxZ - e.minZ + 1 for (ry <- e.minY to e.maxY; rz <- e.minZ to e.maxZ; rx <- e.minX to e.maxX) { - val pos = blockPos.toBlockPos.add(rx, ry, rz) - val x = blockPos.x + rx - val y = blockPos.y + ry - val z = blockPos.z + rz + val pos = blockPos.toBlockPos.offset(rx, ry, rz) val index = (rx - e.minX) + ((rz - e.minZ) + (ry - e.minY) * d) * w - if (world.isBlockLoaded(pos) && !world.isAirBlock(pos)) { + if (world.isLoaded(pos) && !world.isEmptyBlock(pos)) { val blockState = world.getBlockState(pos) - val block = blockState.getBlock - if (block != Blocks.AIR && (includeReplaceable || isFluid(block) || !block.isReplaceable(world, blockPos.toBlockPos))) { + if (!blockState.getBlock.isAir(blockState, world, pos) && (includeReplaceable || blockState.getBlock.isInstanceOf[IFluidBlock] || !blockState.getMaterial.isReplaceable)) { val distance = math.sqrt(rx * rx + ry * ry + rz * rz).toFloat - e.data(index) = e.data(index) * distance * Settings.get.geolyzerNoise + blockState.getBlockHardness(world, pos) + e.data(index) = e.data(index) * distance * Settings.get.geolyzerNoise + blockState.getDestroySpeed(world, pos) } else e.data(index) = 0 } @@ -51,13 +47,11 @@ object EventHandlerVanilla { } } - private def isFluid(block: Block) = FluidRegistry.lookupFluidForBlock(block) != null - - private def getGrowth(blockState: IBlockState) = { - blockState.getPropertyKeys().find(prop => {prop.isInstanceOf[PropertyInteger] && prop.getName() == "age"}) match { + private def getGrowth(blockState: BlockState) = { + blockState.getProperties().find(prop => {prop.isInstanceOf[IntegerProperty] && prop.getName() == "age"}) match { case Some(prop) => { - val propAge = prop.asInstanceOf[PropertyInteger] - Some((blockState.getValue(propAge).toFloat / propAge.getAllowedValues().max) max 0 min 1) + val propAge = prop.asInstanceOf[IntegerProperty] + Some((blockState.getValue(propAge).toFloat / propAge.getPossibleValues().max) max 0 min 1) } case None => None } @@ -66,40 +60,34 @@ object EventHandlerVanilla { @SubscribeEvent def onGeolyzerAnalyze(e: GeolyzerEvent.Analyze) { val world = e.host.world - val blockState = world.getBlockState(e.pos).getActualState(world, e.pos) + val blockState = world.getBlockState(e.pos) val block = blockState.getBlock - e.data += "name" -> Block.REGISTRY.getNameForObject(block) - e.data += "hardness" -> Float.box(blockState.getBlockHardness(world, e.pos)) + e.data += "name" -> block.getRegistryName + e.data += "hardness" -> Float.box(blockState.getDestroySpeed(world, e.pos)) e.data += "harvestLevel" -> Int.box(block.getHarvestLevel(blockState)) - e.data += "harvestTool" -> block.getHarvestTool(blockState) - e.data += "color" -> Int.box(blockState.getMapColor(world, e.pos).colorValue) + e.data += "harvestTool" -> Option(block.getHarvestTool(blockState)).map(_.getName).orNull + e.data += "color" -> Int.box(blockState.getMapColor(world, e.pos).col) // backward compatibility - e.data += "metadata" -> Int.box({ - try { - block.getMetaFromState(blockState) - } catch { - case _ :IllegalArgumentException => 0 - } - }) + e.data += "metadata" -> Int.box(0) e.data += "properties" -> { var props:Map[String, Any] = Map(); - for (prop <- blockState.getProperties().keySet()) { + for (prop <- blockState.getProperties()) { props += prop.getName() -> blockState.getValue(prop) } props } if (Settings.get.insertIdsInConverters) { - e.data += "id" -> Int.box(Block.getIdFromBlock(block)) + e.data += "id" -> Int.box(Block.getId(blockState)) } { - if (block.isInstanceOf[BlockCrops] || block.isInstanceOf[BlockStem] || block == Blocks.COCOA || block == Blocks.NETHER_WART || block == Blocks.CHORUS_FLOWER) { + if (block.isInstanceOf[CropsBlock] || block.isInstanceOf[StemBlock] || block == Blocks.COCOA || block == Blocks.NETHER_WART || block == Blocks.CHORUS_FLOWER) { getGrowth(blockState) - } else if (block == Blocks.MELON_BLOCK || block == Blocks.PUMPKIN || block == Blocks.CACTUS || block == Blocks.REEDS || block == Blocks.CHORUS_PLANT) { + } else if (block == Blocks.MELON || block == Blocks.PUMPKIN || block == Blocks.CACTUS || block == Blocks.SUGAR_CANE || block == Blocks.CHORUS_PLANT) { Some(1f) } else { None diff --git a/src/main/scala/li/cil/oc/integration/minecraft/ModMinecraft.scala b/src/main/scala/li/cil/oc/integration/minecraft/ModMinecraft.scala index 0c7672e33a..9844fc89c2 100644 --- a/src/main/scala/li/cil/oc/integration/minecraft/ModMinecraft.scala +++ b/src/main/scala/li/cil/oc/integration/minecraft/ModMinecraft.scala @@ -8,15 +8,15 @@ import li.cil.oc.integration.util.BundledRedstone import li.cil.oc.integration.util.BundledRedstone.RedstoneProvider import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.block.BlockRedstoneWire -import net.minecraft.init.Blocks -import net.minecraft.util.EnumFacing +import net.minecraft.block.Blocks +import net.minecraft.block.RedstoneWireBlock +import net.minecraft.util.Direction import net.minecraftforge.common.MinecraftForge object ModMinecraft extends ModProxy with RedstoneProvider { def getMod = Mods.Minecraft - def initialize() { + override def initialize() { Driver.add(DriverBeacon) Driver.add(DriverBrewingStand) Driver.add(DriverComparator) @@ -50,20 +50,17 @@ object ModMinecraft extends ModProxy with RedstoneProvider { Driver.add(ConverterItemStack) Driver.add(ConverterNBT) Driver.add(ConverterWorld) - Driver.add(ConverterWorldProvider) - - RecipeHandler.init() BundledRedstone.addProvider(this) MinecraftForge.EVENT_BUS.register(EventHandlerVanilla) } - override def computeInput(pos: BlockPosition, side: EnumFacing): Int = { + override def computeInput(pos: BlockPosition, side: Direction): Int = { val world = pos.world.get math.max(world.computeRedstoneSignal(pos, side), - if (world.getBlock(pos.offset(side)) == Blocks.REDSTONE_WIRE) world.getBlockMetadata(pos.offset(side)).getValue(BlockRedstoneWire.POWER).intValue() else 0) + if (world.getBlock(pos.offset(side)) == Blocks.REDSTONE_WIRE) world.getBlockState(pos.offset(side).toBlockPos).getValue(RedstoneWireBlock.POWER).intValue() else 0) } - override def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int] = null + override def computeBundledInput(pos: BlockPosition, side: Direction): Array[Int] = null } diff --git a/src/main/scala/li/cil/oc/integration/minecraft/RecipeHandler.scala b/src/main/scala/li/cil/oc/integration/minecraft/RecipeHandler.scala deleted file mode 100644 index d4436ccc97..0000000000 --- a/src/main/scala/li/cil/oc/integration/minecraft/RecipeHandler.scala +++ /dev/null @@ -1,77 +0,0 @@ -package li.cil.oc.integration.minecraft - -import com.typesafe.config.Config -import li.cil.oc.common.recipe.ExtendedShapedOreRecipe -import li.cil.oc.common.recipe.ExtendedShapelessOreRecipe -import li.cil.oc.common.recipe.Recipes -import li.cil.oc.common.recipe.Recipes.RecipeException -import net.minecraft.item.ItemStack -import net.minecraft.item.crafting.FurnaceRecipes -import net.minecraftforge.fml.common.registry.GameRegistry -import net.minecraftforge.oredict.OreDictionary - -import scala.collection.convert.WrapAsScala._ -import scala.collection.mutable - -object RecipeHandler { - def init(): Unit = { - Recipes.registerRecipeHandler("shaped", addShapedRecipe) - Recipes.registerRecipeHandler("shapeless", addShapelessRecipe) - Recipes.registerRecipeHandler("furnace", addFurnaceRecipe) - } - - def addShapedRecipe(output: ItemStack, recipe: Config) { - val rows = recipe.getList("input").unwrapped().map { - case row: java.util.List[AnyRef]@unchecked => row.map(Recipes.parseIngredient) - case other => throw new RecipeException(s"Invalid row entry for shaped recipe (not a list: $other).") - } - output.setCount(Recipes.tryGetCount(recipe)) - - var number = -1 - var shape = mutable.ArrayBuffer.empty[String] - val input = mutable.ArrayBuffer.empty[AnyRef] - for (row <- rows) { - val (pattern, ingredients) = row.foldLeft((new StringBuilder, Iterable.empty[AnyRef]))((acc, ingredient) => { - val (pattern, ingredients) = acc - ingredient match { - case _@(_: ItemStack | _: String) => - number += 1 - (pattern.append(('a' + number).toChar), ingredients ++ Iterable(Char.box(('a' + number).toChar), ingredient)) - case _ => (pattern.append(' '), ingredients) - } - }) - shape += pattern.toString - input ++= ingredients - } - if (input.nonEmpty && output.getCount > 0) { - Recipes.addRecipe(new ExtendedShapedOreRecipe(output, shape ++ input: _*)) - } - } - - def addShapelessRecipe(output: ItemStack, recipe: Config) { - val input = recipe.getValue("input").unwrapped() match { - case list: java.util.List[AnyRef]@unchecked => list.map(Recipes.parseIngredient) - case other => Seq(Recipes.parseIngredient(other)) - } - output.setCount(Recipes.tryGetCount(recipe)) - - if (input.nonEmpty && output.getCount > 0) { - Recipes.addRecipe(new ExtendedShapelessOreRecipe(output, input: _*)) - } - } - - def addFurnaceRecipe(output: ItemStack, recipe: Config) { - val input = Recipes.parseIngredient(recipe.getValue("input").unwrapped()) - output.setCount(Recipes.tryGetCount(recipe)) - - input match { - case stack: ItemStack => - FurnaceRecipes.instance.addSmeltingRecipe(stack, output, 0) - case name: String => - for (stack <- OreDictionary.getOres(name)) { - FurnaceRecipes.instance.addSmeltingRecipe(stack, output, 0) - } - case _ => - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/minecraftforge/DriverEnergyStorage.scala b/src/main/scala/li/cil/oc/integration/minecraftforge/DriverEnergyStorage.scala index f241427100..33c45e95a9 100644 --- a/src/main/scala/li/cil/oc/integration/minecraftforge/DriverEnergyStorage.scala +++ b/src/main/scala/li/cil/oc/integration/minecraftforge/DriverEnergyStorage.scala @@ -11,7 +11,7 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.ResultWrapper.result import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World import net.minecraftforge.energy.CapabilityEnergy @@ -22,13 +22,13 @@ import net.minecraftforge.energy.IEnergyStorage */ object DriverEnergyStorage extends DriverBlock { - override def worksWith(world: World, pos: BlockPos, side: EnumFacing): Boolean = world.getTileEntity(pos) match { - case tile: TileEntity if tile.hasCapability(CapabilityEnergy.ENERGY, side) => true + override def worksWith(world: World, pos: BlockPos, side: Direction): Boolean = world.getBlockEntity(pos) match { + case tile: TileEntity if tile.getCapability(CapabilityEnergy.ENERGY, side).isPresent => true case _ => false } - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = world.getTileEntity(pos) match { - case tile: TileEntity if tile.hasCapability(CapabilityEnergy.ENERGY, side) => new Environment(tile.getCapability(CapabilityEnergy.ENERGY, side)) + override def createEnvironment(world: World, pos: BlockPos, side: Direction): ManagedEnvironment = world.getBlockEntity(pos) match { + case tile: TileEntity if tile.getCapability(CapabilityEnergy.ENERGY, side).isPresent => new Environment(tile.getCapability(CapabilityEnergy.ENERGY, side).orElse(null)) case _ => null } diff --git a/src/main/scala/li/cil/oc/integration/minecraftforge/EventHandlerMinecraftForge.scala b/src/main/scala/li/cil/oc/integration/minecraftforge/EventHandlerMinecraftForge.scala index 3f7e530c04..2650260f26 100644 --- a/src/main/scala/li/cil/oc/integration/minecraftforge/EventHandlerMinecraftForge.scala +++ b/src/main/scala/li/cil/oc/integration/minecraftforge/EventHandlerMinecraftForge.scala @@ -5,14 +5,16 @@ import li.cil.oc.common.tileentity.traits.PowerAcceptor import li.cil.oc.integration.util.Power import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier import net.minecraftforge.energy.CapabilityEnergy import net.minecraftforge.energy.IEnergyStorage import net.minecraftforge.event.AttachCapabilitiesEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent object EventHandlerMinecraftForge { @@ -20,39 +22,50 @@ object EventHandlerMinecraftForge { def onAttachCapabilities(event: AttachCapabilitiesEvent[TileEntity]): Unit = { event.getObject match { case tileEntity: PowerAcceptor => - event.addCapability(ProviderEnergy, new Provider(tileEntity)) + val provider = new Provider(tileEntity) + event.addCapability(ProviderEnergy, provider) + event.addListener(new Runnable { + override def run = provider.invalidate + }) case _ => } } def canCharge(stack: ItemStack): Boolean = - if (stack.hasCapability(CapabilityEnergy.ENERGY, null)) stack.getCapability(CapabilityEnergy.ENERGY, null) match { + stack.getCapability(CapabilityEnergy.ENERGY, null).orElse(null) match { case storage: IEnergyStorage => storage.canReceive case _ => false - } else false + } def charge(stack: ItemStack, amount: Double, simulate: Boolean): Double = - if (stack.hasCapability(CapabilityEnergy.ENERGY, null)) stack.getCapability(CapabilityEnergy.ENERGY, null) match { + stack.getCapability(CapabilityEnergy.ENERGY, null).orElse(null) match { case storage: IEnergyStorage => amount - Power.fromRF(storage.receiveEnergy(Power.toRF(amount), simulate)) case _ => amount - } else amount + } val ProviderEnergy: ResourceLocation = new ResourceLocation(OpenComputers.ID, "forgeenergy") class Provider(tile: PowerAcceptor) extends ICapabilityProvider { - private val providers = EnumFacing.VALUES.map(side => new EnergyStorageImpl(tile, side)) - private val nullProvider = new EnergyStorageImpl(tile, null) + private val providers = Direction.values.map(side => LazyOptional.of(new NonNullSupplier[EnergyStorageImpl] { + override def get = new EnergyStorageImpl(tile, side) + })) + private val nullProvider = LazyOptional.of(new NonNullSupplier[EnergyStorageImpl] { + override def get = new EnergyStorageImpl(tile, null) + }) - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = capability == CapabilityEnergy.ENERGY + def invalidate(): Unit = { + for (provider <- providers) provider.invalidate + nullProvider.invalidate + } - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { if (capability == CapabilityEnergy.ENERGY) { - (if (facing == null) nullProvider else providers(facing.getIndex)).asInstanceOf[T] - } else null.asInstanceOf[T] + (if (facing == null) nullProvider.cast[T] else providers(facing.get3DDataValue)).cast[T] + } else LazyOptional.empty[T] } - class EnergyStorageImpl(val tile: PowerAcceptor, val side: EnumFacing) extends IEnergyStorage { + class EnergyStorageImpl(val tile: PowerAcceptor, val side: Direction) extends IEnergyStorage { override def getEnergyStored: Int = Power.toRF(tile.globalBuffer(side)) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ConverterLinkedCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ConverterLinkedCard.scala index 93138a93b4..d7b3a299c9 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ConverterLinkedCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ConverterLinkedCard.scala @@ -9,7 +9,7 @@ import li.cil.oc.api.driver.Converter import li.cil.oc.server.component import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ConverterLinkedCard extends Converter { lazy val linkedCard: ItemInfo = api.Items.get(Constants.ItemName.LinkedCard) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ConverterNanomachines.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ConverterNanomachines.scala index 2eb0d27027..8116a9d362 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ConverterNanomachines.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ConverterNanomachines.scala @@ -9,7 +9,7 @@ import li.cil.oc.api.driver.Converter import li.cil.oc.common.item.data.NanomachineData import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object ConverterNanomachines extends Converter { lazy val nanomachines = api.Items.get(Constants.ItemName.Nanomachines) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverAPU.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverAPU.scala index 4072a146ff..2f1e145e2d 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverAPU.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverAPU.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.driver.item.HostAware import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common import li.cil.oc.common.Tier -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component import net.minecraft.item.ItemStack @@ -18,7 +17,7 @@ object DriverAPU extends DriverCPU with HostAware { api.Items.get(Constants.ItemName.APUCreative)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else gpuTier(stack) match { case Tier.One => new component.APU(Tier.One) case Tier.Two => new component.APU(Tier.Two) @@ -27,14 +26,14 @@ object DriverAPU extends DriverCPU with HostAware { } override def cpuTier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(apu: common.item.APU) => apu.cpuTier + stack.getItem match { + case apu: common.item.APU => apu.cpuTier case _ => Tier.One } def gpuTier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(apu: common.item.APU) => apu.gpuTier + stack.getItem match { + case apu: common.item.APU => apu.gpuTier case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala index ee5a35adca..c421e4aff7 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverCPU.scala @@ -7,14 +7,13 @@ import li.cil.oc.api import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component import li.cil.oc.server.machine.luac.NativeLuaArchitecture import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ object DriverCPU extends DriverCPU @@ -31,8 +30,8 @@ abstract class DriverCPU extends Item with api.driver.item.MutableProcessor with override def tier(stack: ItemStack) = cpuTier(stack) def cpuTier(stack: ItemStack): Int = - Delegator.subItem(stack) match { - case Some(cpu: item.CPU) => cpu.cpuTier + stack.getItem match { + case cpu: item.CPU => cpu.cpuTier case _ => Tier.One } @@ -41,8 +40,8 @@ abstract class DriverCPU extends Item with api.driver.item.MutableProcessor with override def allArchitectures = api.Machine.architectures.toList override def architecture(stack: ItemStack): Class[_ <: api.machine.Architecture] = { - if (stack.hasTagCompound) { - val archClass = stack.getTagCompound.getString(Settings.namespace + "archClass") match { + if (stack.hasTag) { + val archClass = stack.getTag.getString(Settings.namespace + "archClass") match { case clazz if clazz == classOf[NativeLuaArchitecture].getName => // Migrate old saved CPUs to new versions (since the class they refer still // exists, but is abstract, which would lead to issues). @@ -52,8 +51,8 @@ abstract class DriverCPU extends Item with api.driver.item.MutableProcessor with if (!archClass.isEmpty) try return Class.forName(archClass).asSubclass(classOf[api.machine.Architecture]) catch { case t: Throwable => OpenComputers.log.warn("Failed getting class for CPU architecture. Resetting CPU to use the default.", t) - stack.getTagCompound.removeTag(Settings.namespace + "archClass") - stack.getTagCompound.removeTag(Settings.namespace + "archName") + stack.getTag.remove(Settings.namespace + "archClass") + stack.getTag.remove(Settings.namespace + "archName") } } api.Machine.architectures.headOption.orNull @@ -61,9 +60,9 @@ abstract class DriverCPU extends Item with api.driver.item.MutableProcessor with override def setArchitecture(stack: ItemStack, architecture: Class[_ <: api.machine.Architecture]): Unit = { if (!worksWith(stack)) throw new IllegalArgumentException("Unsupported processor type.") - if (!stack.hasTagCompound) stack.setTagCompound(new NBTTagCompound()) - stack.getTagCompound.setString(Settings.namespace + "archClass", architecture.getName) - stack.getTagCompound.setString(Settings.namespace + "archName", api.Machine.getArchitectureName(architecture)) + val data = stack.getOrCreateTag + data.putString(Settings.namespace + "archClass", architecture.getName) + data.putString(Settings.namespace + "archName", api.Machine.getArchitectureName(architecture)) } override def getCallBudget(stack: ItemStack): Double = Settings.get.callBudgets(tier(stack) max Tier.One min Tier.Three) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverComponentBus.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverComponentBus.scala index eae7874692..e372a91173 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverComponentBus.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverComponentBus.scala @@ -8,7 +8,6 @@ import li.cil.oc.api.driver.item.Processor import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import net.minecraft.item.ItemStack object DriverComponentBus extends Item with Processor { @@ -24,14 +23,14 @@ object DriverComponentBus extends Item with Processor { // Clamp item tier because the creative bus needs to fit into tier 3 slots. override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(bus: item.ComponentBus) => bus.tier min Tier.Three + stack.getItem match { + case bus: item.ComponentBus => bus.tier min Tier.Three case _ => Tier.One } override def supportedComponents(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(bus: item.ComponentBus) => Settings.get.cpuComponentSupport(bus.tier) + stack.getItem match { + case bus: item.ComponentBus => Settings.get.cpuComponentSupport(bus.tier) case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerCard.scala index 2e3531ae60..5a174f9710 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerCard.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.driver.item.Container import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import net.minecraft.item.ItemStack object DriverContainerCard extends Item with Container { @@ -25,8 +24,8 @@ object DriverContainerCard extends Item with Container { override def providedTier(stack: ItemStack) = tier(stack) override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(container: item.UpgradeContainerCard) => container.tier + stack.getItem match { + case container: item.UpgradeContainerCard => container.tier case _ => Tier.One } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerUpgrade.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerUpgrade.scala index fc99bb9d3c..1a274a99d1 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerUpgrade.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverContainerUpgrade.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.driver.item.Container import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import net.minecraft.item.ItemStack object DriverContainerUpgrade extends Item with Container { @@ -25,8 +24,8 @@ object DriverContainerUpgrade extends Item with Container { override def providedTier(stack: ItemStack) = tier(stack) override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(container: item.UpgradeContainerUpgrade) => container.tier + stack.getItem match { + case container: item.UpgradeContainerUpgrade => container.tier case _ => Tier.One } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverDataCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverDataCard.scala index 75410f4227..0f57efe557 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverDataCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverDataCard.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common import li.cil.oc.common.Slot import li.cil.oc.common.Tier -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component import net.minecraft.item.ItemStack @@ -18,7 +17,7 @@ object DriverDataCard extends Item { api.Items.get(Constants.ItemName.DataCardTier3)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else tier(stack) match { case Tier.One => new component.DataCard.Tier1() case Tier.Two => new component.DataCard.Tier2() @@ -29,8 +28,8 @@ object DriverDataCard extends Item { override def slot(stack: ItemStack) = Slot.Card override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(data: common.item.DataCard) => data.tier + stack.getItem match { + case data: common.item.DataCard => data.tier case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverDebugCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverDebugCard.scala index c469c7be96..94150fc1cc 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverDebugCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverDebugCard.scala @@ -13,7 +13,7 @@ object DriverDebugCard extends Item { api.Items.get(Constants.ItemName.DebugCard)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.DebugCard(host) override def slot(stack: ItemStack) = Slot.Card diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverDiskDriveMountable.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverDiskDriveMountable.scala index 8a275d1f98..b4d5d52f28 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverDiskDriveMountable.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverDiskDriveMountable.scala @@ -9,7 +9,7 @@ import li.cil.oc.common.Slot import li.cil.oc.server.component import li.cil.oc.util.ExtendedInventory._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT object DriverDiskDriveMountable extends Item with HostAware { override def worksWith(stack: ItemStack): Boolean = isOneOf(stack, @@ -22,10 +22,5 @@ object DriverDiskDriveMountable extends Item with HostAware { override def slot(stack: ItemStack): String = Slot.RackMountable - override def dataTag(stack: ItemStack): NBTTagCompound = { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - stack.getTagCompound - } + override def dataTag(stack: ItemStack): CompoundNBT = stack.getOrCreateTag } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverEEPROM.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverEEPROM.scala index fa309c537b..30cf0689b6 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverEEPROM.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverEEPROM.scala @@ -14,7 +14,7 @@ object DriverEEPROM extends Item { api.Items.get(Constants.ItemName.EEPROM)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.EEPROM() override def slot(stack: ItemStack) = Slot.EEPROM diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala index ab8177978a..b40f570039 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverFileSystem.scala @@ -8,15 +8,15 @@ import li.cil.oc.api import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common.Loot import li.cil.oc.common.Slot -import li.cil.oc.common.item.Delegator import li.cil.oc.common.item.FloppyDisk import li.cil.oc.common.item.HardDiskDrive import li.cil.oc.common.item.data.DriveData import li.cil.oc.server.component.Drive import li.cil.oc.server.fs.FileSystem.{ItemLabel, ReadOnlyLabel} import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.common.DimensionManager +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.ResourceLocation +import net.minecraftforge.fml.server.ServerLifecycleHooks object DriverFileSystem extends Item { val UUIDVerifier = """^([0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})$""".r @@ -26,36 +26,37 @@ object DriverFileSystem extends Item { api.Items.get(Constants.ItemName.HDDTier2), api.Items.get(Constants.ItemName.HDDTier3), api.Items.get(Constants.ItemName.Floppy)) && - (!stack.hasTagCompound || !stack.getTagCompound.hasKey(Settings.namespace + "lootPath")) + (!stack.hasTag || !stack.getTag.contains(Settings.namespace + "lootPath")) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null - else Delegator.subItem(stack) match { - case Some(hdd: HardDiskDrive) => createEnvironment(stack, hdd.kiloBytes * 1024, hdd.platterCount, host, hdd.tier + 2) - case Some(disk: FloppyDisk) => createEnvironment(stack, Settings.get.floppySize * 1024, 1, host, 1) + if (host.world != null && host.world.isClientSide) null + else stack.getItem match { + case hdd: HardDiskDrive => createEnvironment(stack, hdd.kiloBytes * 1024, hdd.platterCount, host, hdd.tier + 2) + case disk: FloppyDisk => createEnvironment(stack, Settings.get.floppySize * 1024, 1, host, 1) case _ => null } override def slot(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(hdd: HardDiskDrive) => Slot.HDD - case Some(disk: FloppyDisk) => Slot.Floppy + stack.getItem match { + case hdd: HardDiskDrive => Slot.HDD + case disk: FloppyDisk => Slot.Floppy case _ => throw new IllegalArgumentException() } override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(hdd: HardDiskDrive) => hdd.tier + stack.getItem match { + case hdd: HardDiskDrive => hdd.tier case _ => 0 } - private def createEnvironment(stack: ItemStack, capacity: Int, platterCount: Int, host: EnvironmentHost, speed: Int) = if (DimensionManager.getWorld(0) != null) { - if (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "lootFactory")) { + private def createEnvironment(stack: ItemStack, capacity: Int, platterCount: Int, host: EnvironmentHost, speed: Int) = if (ServerLifecycleHooks.getCurrentServer != null) { + if (stack.hasTag && stack.getTag.contains(Settings.namespace + "lootFactory")) { // Loot disk, create file system using factory callback. - Loot.factories.get(stack.getTagCompound.getString(Settings.namespace + "lootFactory")) match { + val lootFactory = new ResourceLocation(stack.getTag.getString(Settings.namespace + "lootFactory")) + Loot.factories.get(lootFactory) match { case Some(factory) => val label = - if (dataTag(stack).hasKey(Settings.namespace + "fs.label")) + if (dataTag(stack).contains(Settings.namespace + "fs.label")) dataTag(stack).getString(Settings.namespace + "fs.label") else null api.FileSystem.asManagedEnvironment(factory.call(), label, host, Settings.resourceDomain + ":floppy_access") @@ -90,13 +91,13 @@ object DriverFileSystem extends Item { } else null - private def addressFromTag(tag: NBTTagCompound) = - if (tag.hasKey("node") && tag.getCompoundTag("node").hasKey("address")) { - tag.getCompoundTag("node").getString("address") match { + private def addressFromTag(tag: CompoundNBT) = + if (tag.contains("node") && tag.getCompound("node").contains("address")) { + tag.getCompound("node").getString("address") match { case UUIDVerifier(address) => address case _ => // Invalid disk address. val newAddress = java.util.UUID.randomUUID().toString - tag.getCompoundTag("node").setString("address", newAddress) + tag.getCompound("node").putString("address", newAddress) OpenComputers.log.warn(s"Generated new address for disk '${newAddress}'.") newAddress } @@ -114,15 +115,15 @@ object DriverFileSystem extends Item { private final val LabelTag = Settings.namespace + "fs.label" - override def load(nbt: NBTTagCompound) { - if (nbt.hasKey(LabelTag)) { + override def loadData(nbt: CompoundNBT) { + if (nbt.contains(LabelTag)) { label = Option(nbt.getString(LabelTag)) } } - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { label match { - case Some(value) => nbt.setString(LabelTag, value) + case Some(value) => nbt.putString(LabelTag, value) case _ => } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverGeolyzer.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverGeolyzer.scala index afa811ee13..1982c76947 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverGeolyzer.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverGeolyzer.scala @@ -14,7 +14,7 @@ object DriverGeolyzer extends Item with HostAware { api.Items.get(Constants.BlockName.Geolyzer)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.Geolyzer(host) override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverGraphicsCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverGraphicsCard.scala index bc9f3a477f..7803d283a6 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverGraphicsCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverGraphicsCard.scala @@ -8,7 +8,6 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common import li.cil.oc.common.Slot import li.cil.oc.common.Tier -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component import net.minecraft.item.ItemStack @@ -19,7 +18,7 @@ object DriverGraphicsCard extends Item with HostAware { api.Items.get(Constants.ItemName.GraphicsCardTier3)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else tier(stack) match { case Tier.One => new component.GraphicsCard(Tier.One) case Tier.Two => new component.GraphicsCard(Tier.Two) @@ -30,8 +29,8 @@ object DriverGraphicsCard extends Item with HostAware { override def slot(stack: ItemStack) = Slot.Card override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(gpu: common.item.GraphicsCard) => gpu.gpuTier + stack.getItem match { + case gpu: common.item.GraphicsCard => gpu.gpuTier case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverInternetCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverInternetCard.scala index e4a718bb1c..a82ab1c97e 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverInternetCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverInternetCard.scala @@ -14,7 +14,7 @@ object DriverInternetCard extends Item { api.Items.get(Constants.ItemName.InternetCard)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.InternetCard() override def slot(stack: ItemStack) = Slot.Card diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverLinkedCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverLinkedCard.scala index e83a08d5c9..0691608573 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverLinkedCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverLinkedCard.scala @@ -14,7 +14,7 @@ object DriverLinkedCard extends Item { api.Items.get(Constants.ItemName.LinkedCard)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.LinkedCard() override def slot(stack: ItemStack) = Slot.Card diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala index 08e6f3db3d..ab8c63ea13 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverLootDisk.scala @@ -9,7 +9,9 @@ import li.cil.oc.api import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common.Slot import net.minecraft.item.ItemStack -import net.minecraftforge.common.DimensionManager +import net.minecraft.util.ResourceLocation +import net.minecraft.world.storage.FolderName +import net.minecraftforge.fml.server.ServerLifecycleHooks // This is deprecated and kept for compatibility with old saves. // As of OC 1.5.10, loot disks are generated using normal floppies, and using @@ -17,21 +19,21 @@ import net.minecraftforge.common.DimensionManager object DriverLootDisk extends Item { override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get(Constants.ItemName.Floppy)) && - (stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "lootPath")) + (stack.hasTag && stack.getTag.contains(Settings.namespace + "lootPath")) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (!host.world.isRemote && stack.hasTagCompound && DimensionManager.getWorld(0) != null) { - val lootPath = "loot/" + stack.getTagCompound.getString(Settings.namespace + "lootPath") - val savePath = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + lootPath) + if (!host.world.isClientSide && stack.hasTag && ServerLifecycleHooks.getCurrentServer != null) { + val lootPath = Settings.savePath + "loot/" + stack.getTag.getString(Settings.namespace + "lootPath") + val savePath = ServerLifecycleHooks.getCurrentServer.getWorldPath(new FolderName(lootPath)).toFile val fs = if (savePath.exists && savePath.isDirectory) { api.FileSystem.fromSaveDirectory(lootPath, 0, false) } else { - api.FileSystem.fromClass(OpenComputers.getClass, Settings.resourceDomain, lootPath) + api.FileSystem.fromResource(new ResourceLocation(Settings.resourceDomain, lootPath)) } val label = - if (dataTag(stack).hasKey(Settings.namespace + "fs.label")) { + if (dataTag(stack).contains(Settings.namespace + "fs.label")) { dataTag(stack).getString(Settings.namespace + "fs.label") } else null diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverMemory.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverMemory.scala index 2d3a4f0993..440efc7a3b 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverMemory.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverMemory.scala @@ -6,13 +6,12 @@ import li.cil.oc.api import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component import net.minecraft.item.ItemStack object DriverMemory extends Item with api.driver.item.Memory with api.driver.item.CallBudget { - override def amount(stack: ItemStack) = Delegator.subItem(stack) match { - case Some(memory: item.Memory) => + override def amount(stack: ItemStack) = stack.getItem match { + case memory: item.Memory => val sizes = Settings.get.ramSizes Settings.get.ramSizes(memory.tier max 0 min (sizes.length - 1)) case _ => 0.0 @@ -31,8 +30,8 @@ object DriverMemory extends Item with api.driver.item.Memory with api.driver.ite override def slot(stack: ItemStack) = Slot.Memory override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(memory: item.Memory) => memory.tier / 2 + stack.getItem match { + case memory: item.Memory => memory.tier / 2 case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverMotionSensor.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverMotionSensor.scala index a0416e4d69..d4e4ffba1d 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverMotionSensor.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverMotionSensor.scala @@ -15,7 +15,7 @@ object DriverMotionSensor extends Item with HostAware { api.Items.get(Constants.BlockName.MotionSensor)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.MotionSensor(host) override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverNetworkCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverNetworkCard.scala index 70fd0ca611..fa588a42c6 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverNetworkCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverNetworkCard.scala @@ -14,7 +14,7 @@ object DriverNetworkCard extends Item with HostAware { api.Items.get(Constants.ItemName.NetworkCard)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.NetworkCard(host) override def slot(stack: ItemStack) = Slot.Card diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverRedstoneCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverRedstoneCard.scala index c856b60e35..558c4ded29 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverRedstoneCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverRedstoneCard.scala @@ -8,7 +8,6 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.common.tileentity.traits.BundledRedstoneAware import li.cil.oc.common.tileentity.traits.RedstoneAware import li.cil.oc.integration.util.BundledRedstone @@ -22,7 +21,7 @@ object DriverRedstoneCard extends Item with HostAware { api.Items.get(Constants.ItemName.RedstoneCardTier2)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else { val isAdvanced = tier(stack) == Tier.Two val hasBundled = BundledRedstone.isAvailable && isAdvanced @@ -43,8 +42,8 @@ object DriverRedstoneCard extends Item with HostAware { override def slot(stack: ItemStack) = Slot.Card override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(card: item.RedstoneCard) => card.tier + stack.getItem match { + case card: item.RedstoneCard => card.tier case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverServer.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverServer.scala index b3033da84a..12f4f7e56c 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverServer.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverServer.scala @@ -9,7 +9,7 @@ import li.cil.oc.common.Slot import li.cil.oc.server.component import li.cil.oc.util.ExtendedInventory._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT object DriverServer extends Item with HostAware { override def worksWith(stack: ItemStack): Boolean = isOneOf(stack, @@ -25,10 +25,5 @@ object DriverServer extends Item with HostAware { override def slot(stack: ItemStack): String = Slot.RackMountable - override def dataTag(stack: ItemStack): NBTTagCompound = { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - stack.getTagCompound - } + override def dataTag(stack: ItemStack): CompoundNBT = stack.getOrCreateTag } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverTablet.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverTablet.scala index 8507051806..6f21c60c04 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverTablet.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverTablet.scala @@ -10,7 +10,7 @@ import li.cil.oc.common.Slot import li.cil.oc.common.item.Tablet import li.cil.oc.common.item.data.TabletData import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraftforge.common.util.Constants.NBT object DriverTablet extends Item { @@ -18,7 +18,7 @@ object DriverTablet extends Item { api.Items.get(Constants.ItemName.Tablet)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else { Tablet.Server.cache.invalidate(Tablet.getId(stack)) val data = new TabletData(stack) @@ -28,7 +28,7 @@ object DriverTablet extends Item { case Some(environment) => environment.node match { case component: Component => component.setVisibility(Visibility.Network) - environment.save(dataTag(stack)) + environment.saveData(dataTag(stack)) environment case _ => null } @@ -44,21 +44,21 @@ object DriverTablet extends Item { case fs if !fs.isEmpty => DriverFileSystem.worksWith(fs) case _ => false } - if (index >= 0 && stack.hasTagCompound && stack.getTagCompound.hasKey(Settings.namespace + "items")) { - val baseTag = stack.getTagCompound.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).getCompoundTagAt(index) - if (!baseTag.hasKey("item")) { - baseTag.setTag("item", new NBTTagCompound()) + if (index >= 0 && stack.hasTag && stack.getTag.contains(Settings.namespace + "items")) { + val baseTag = stack.getTag.getList(Settings.namespace + "items", NBT.TAG_COMPOUND).getCompound(index) + if (!baseTag.contains("item")) { + baseTag.put("item", new CompoundNBT()) } - val itemTag = baseTag.getCompoundTag("item") - if (!itemTag.hasKey("tag")) { - itemTag.setTag("tag", new NBTTagCompound()) + val itemTag = baseTag.getCompound("item") + if (!itemTag.contains("tag")) { + itemTag.put("tag", new CompoundNBT()) } - val stackTag = itemTag.getCompoundTag("tag") - if (!stackTag.hasKey(Settings.namespace + "data")) { - stackTag.setTag(Settings.namespace + "data", new NBTTagCompound()) + val stackTag = itemTag.getCompound("tag") + if (!stackTag.contains(Settings.namespace + "data")) { + stackTag.put(Settings.namespace + "data", new CompoundNBT()) } - stackTag.getCompoundTag(Settings.namespace + "data") + stackTag.getCompound(Settings.namespace + "data") } - else new NBTTagCompound() + else new CompoundNBT() } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverTransposer.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverTransposer.scala index a2637d1048..79d54c22a9 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverTransposer.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverTransposer.scala @@ -14,7 +14,7 @@ object DriverTransposer extends Item with HostAware { api.Items.get(Constants.BlockName.Transposer)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.Transposer.Upgrade(host) override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeAngel.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeAngel.scala index 3f7a1013e6..0949f2e021 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeAngel.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeAngel.scala @@ -14,7 +14,7 @@ object DriverUpgradeAngel extends Item with HostAware { api.Items.get(Constants.ItemName.AngelUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.UpgradeAngel() override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeBattery.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeBattery.scala index ce2ba4f6fb..3727d7ebf1 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeBattery.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeBattery.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component import net.minecraft.item.ItemStack @@ -18,14 +17,14 @@ object DriverUpgradeBattery extends Item with HostAware { api.Items.get(Constants.ItemName.BatteryUpgradeTier3)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.UpgradeBattery(tier(stack)) override def slot(stack: ItemStack) = Slot.Upgrade override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(battery: item.UpgradeBattery) => battery.tier + stack.getItem match { + case battery: item.UpgradeBattery => battery.tier case _ => Tier.One } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeChunkloader.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeChunkloader.scala index 36532b63b6..8f89e69f84 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeChunkloader.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeChunkloader.scala @@ -15,7 +15,7 @@ object DriverUpgradeChunkloader extends Item with HostAware { api.Items.get(Constants.ItemName.ChunkloaderUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.UpgradeChunkloader(host) override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeCrafting.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeCrafting.scala index 6fab0a16ff..e71c32b2a4 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeCrafting.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeCrafting.scala @@ -16,7 +16,7 @@ object DriverUpgradeCrafting extends Item with HostAware { api.Items.get(Constants.ItemName.CraftingUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case robot: EnvironmentHost with Robot => new component.UpgradeCrafting(robot) case _ => null diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeDatabase.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeDatabase.scala index c9fdc5fe45..188f4f7e34 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeDatabase.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeDatabase.scala @@ -7,9 +7,8 @@ import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.inventory.DatabaseInventory import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack object DriverUpgradeDatabase extends Item with api.driver.item.HostAware { @@ -19,18 +18,18 @@ object DriverUpgradeDatabase extends Item with api.driver.item.HostAware { api.Items.get(Constants.ItemName.DatabaseUpgradeTier3)) override def createEnvironment(stack: ItemStack, host: api.network.EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.UpgradeDatabase(new DatabaseInventory { override def container = stack - override def isUsableByPlayer(player: EntityPlayer) = false + override def stillValid(player: PlayerEntity) = false }) override def slot(stack: ItemStack) = Slot.Upgrade override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(database: item.UpgradeDatabase) => database.tier + stack.getItem match { + case database: item.UpgradeDatabase => database.tier case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeGenerator.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeGenerator.scala index dae2f6999b..2caf6bf0d9 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeGenerator.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeGenerator.scala @@ -16,7 +16,7 @@ object DriverUpgradeGenerator extends Item with HostAware { api.Items.get(Constants.ItemName.GeneratorUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case host: internal.Agent => new component.UpgradeGenerator(host) case _ => null diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeHover.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeHover.scala index 7efd881e65..15e344b77c 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeHover.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeHover.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.driver.item.HostAware import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import net.minecraft.item.ItemStack object DriverUpgradeHover extends Item with HostAware { @@ -20,8 +19,8 @@ object DriverUpgradeHover extends Item with HostAware { override def slot(stack: ItemStack) = Slot.Upgrade override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(upgrade: item.UpgradeHover) => upgrade.tier + stack.getItem match { + case upgrade: item.UpgradeHover => upgrade.tier case _ => Tier.One } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeInventoryController.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeInventoryController.scala index 85897d72ad..f8b429d25e 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeInventoryController.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeInventoryController.scala @@ -18,7 +18,7 @@ object DriverUpgradeInventoryController extends Item with HostAware { api.Items.get(Constants.ItemName.InventoryControllerUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case host: EnvironmentHost with Adapter => new component.UpgradeInventoryController.Adapter(host) case host: EnvironmentHost with Drone => new component.UpgradeInventoryController.Drone(host) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeLeash.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeLeash.scala index 0af34be1c8..e765b16513 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeLeash.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeLeash.scala @@ -16,7 +16,7 @@ object DriverUpgradeLeash extends Item with HostAware { api.Items.get(Constants.ItemName.LeashUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case entity: Entity => new component.UpgradeLeash(entity) case _ => null diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala index fbd3bf62b1..47227398ba 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeMF.scala @@ -6,10 +6,15 @@ import li.cil.oc.api.network.{EnvironmentHost, ManagedEnvironment} import li.cil.oc.common.{Slot, Tier} import li.cil.oc.server.component import li.cil.oc.util.BlockPosition +import li.cil.oc.util.RotationHelper import li.cil.oc.{Constants, Settings, api} import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing -import net.minecraftforge.common.DimensionManager +import net.minecraft.util.Direction +import net.minecraft.util.RegistryKey +import net.minecraft.util.ResourceLocation +import net.minecraft.util.registry.Registry +import net.minecraft.world.server.ServerWorld +import net.minecraftforge.fml.server.ServerLifecycleHooks /** * @author Vexatos @@ -26,14 +31,16 @@ object DriverUpgradeMF extends Item with HostAware { override def tier(stack: ItemStack) = Tier.Three override def createEnvironment(stack: ItemStack, host: EnvironmentHost): ManagedEnvironment = { - if (host.world != null && !host.world.isRemote) { - if (stack.hasTagCompound) { - stack.getTagCompound.getIntArray(Settings.namespace + "coord") match { - case Array(x, y, z, dim, side) => - Option(DimensionManager.getWorld(dim)) match { - case Some(world) => return new component.UpgradeMF(host, BlockPosition(x, y, z, world), EnumFacing.getFront(side)) + if (host.world != null && !host.world.isClientSide) { + if (stack.hasTag) { + stack.getTag.getIntArray(Settings.namespace + "coord") match { + case Array(x, y, z, side) => { + val dimension = new ResourceLocation(stack.getTag.getString(Settings.namespace + "dimension")) + ServerLifecycleHooks.getCurrentServer.getLevel(RegistryKey.create(Registry.DIMENSION_REGISTRY, dimension)) match { + case world: ServerWorld => return new component.UpgradeMF(host, BlockPosition(x, y, z, world), Direction.from3DDataValue(side)) case _ => // Invalid dimension ID } + } case _ => // Invalid tag } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeNavigation.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeNavigation.scala index 150155f82d..1f18af0885 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeNavigation.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeNavigation.scala @@ -16,7 +16,7 @@ object DriverUpgradeNavigation extends Item with HostAware { api.Items.get(Constants.ItemName.NavigationUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case rotatable: EnvironmentHost with Rotatable => new component.UpgradeNavigation(rotatable) case _ => null diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradePiston.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradePiston.scala index 64b40bd11b..5e9eb7e311 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradePiston.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradePiston.scala @@ -15,7 +15,7 @@ object DriverUpgradePiston extends Item with HostAware { api.Items.get(Constants.ItemName.PistonUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case host: internal.Drone => new component.UpgradePiston.Drone(host) case host: internal.Tablet => new component.UpgradePiston.Tablet(host) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSign.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSign.scala index 58638827d9..7d5ba624d0 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSign.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSign.scala @@ -18,7 +18,7 @@ object DriverUpgradeSign extends Item with HostAware { api.Items.get(Constants.ItemName.SignUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case rotatable: EnvironmentHost with Rotatable => new UpgradeSignInRotatable(rotatable) case adapter: EnvironmentHost with Adapter => new UpgradeSignInAdapter(adapter) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSolarGenerator.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSolarGenerator.scala index f91a21c30f..f6d729953e 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSolarGenerator.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeSolarGenerator.scala @@ -14,7 +14,7 @@ object DriverUpgradeSolarGenerator extends Item with HostAware { api.Items.get(Constants.ItemName.SolarGeneratorUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.UpgradeSolarGenerator(host) override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeStickyPiston.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeStickyPiston.scala index 0c1bb66615..7690ccde73 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeStickyPiston.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeStickyPiston.scala @@ -15,7 +15,7 @@ object DriverUpgradeStickyPiston extends Item with HostAware { api.Items.get(Constants.ItemName.StickyPistonUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost): ManagedEnvironment = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case host: internal.Drone => new component.UpgradeStickyPiston.Drone(host) case host: internal.Tablet => new component.UpgradeStickyPiston.Tablet(host) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTank.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTank.scala index 618875afcf..02612d6ecd 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTank.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTank.scala @@ -13,7 +13,7 @@ object DriverUpgradeTank extends Item with HostAware { api.Items.get(Constants.ItemName.TankUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else new component.UpgradeTank(host, 16000) override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTankController.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTankController.scala index b66090ffe7..e225714152 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTankController.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTankController.scala @@ -18,7 +18,7 @@ object DriverUpgradeTankController extends Item with HostAware { api.Items.get(Constants.ItemName.TankControllerUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case host: EnvironmentHost with Adapter => new component.UpgradeTankController.Adapter(host) case host: EnvironmentHost with Drone => new component.UpgradeTankController.Drone(host) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTractorBeam.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTractorBeam.scala index 63306e940c..8f6f388457 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTractorBeam.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTractorBeam.scala @@ -19,7 +19,7 @@ object DriverUpgradeTractorBeam extends Item with HostAware { api.Items.get(Constants.ItemName.TractorBeamUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else host match { case drone: Drone => new UpgradeTractorBeam.Drone(drone) case robot: Robot => new component.UpgradeTractorBeam.Player(host, robot.player) diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTrading.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTrading.scala index db66594eb2..603500d8a2 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTrading.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverUpgradeTrading.scala @@ -16,7 +16,7 @@ object DriverUpgradeTrading extends Item with HostAware { api.Items.get(Constants.ItemName.TradingUpgrade)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world.isRemote) null + if (host.world.isClientSide) null else new UpgradeTrading(host) override def slot(stack: ItemStack) = Slot.Upgrade diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/DriverWirelessNetworkCard.scala b/src/main/scala/li/cil/oc/integration/opencomputers/DriverWirelessNetworkCard.scala index 485e1de094..c7ae3313cd 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/DriverWirelessNetworkCard.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/DriverWirelessNetworkCard.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.common import li.cil.oc.common.Slot import li.cil.oc.common.Tier -import li.cil.oc.common.item.Delegator import li.cil.oc.server.component import net.minecraft.item.ItemStack @@ -17,7 +16,7 @@ object DriverWirelessNetworkCard extends Item { api.Items.get(Constants.ItemName.WirelessNetworkCardTier2)) override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = - if (host.world != null && host.world.isRemote) null + if (host.world != null && host.world.isClientSide) null else tier(stack) match { case Tier.One => new component.WirelessNetworkCard.Tier1(host) case Tier.Two => new component.WirelessNetworkCard.Tier2(host) @@ -27,8 +26,8 @@ object DriverWirelessNetworkCard extends Item { override def slot(stack: ItemStack) = Slot.Card override def tier(stack: ItemStack) = - Delegator.subItem(stack) match { - case Some(card: common.item.WirelessNetworkCard) => card.tier + stack.getItem match { + case card: common.item.WirelessNetworkCard => card.tier case _ => Tier.One } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/EnvironmentProviderBlocks.scala b/src/main/scala/li/cil/oc/integration/opencomputers/EnvironmentProviderBlocks.scala index 74513be7ba..aa43318302 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/EnvironmentProviderBlocks.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/EnvironmentProviderBlocks.scala @@ -10,7 +10,7 @@ import li.cil.oc.integration.util.BundledRedstone import li.cil.oc.server.component import li.cil.oc.server.machine.Machine import net.minecraft.block.Block -import net.minecraft.item.ItemBlock +import net.minecraft.item.BlockItem import net.minecraft.item.ItemStack /** @@ -21,7 +21,7 @@ import net.minecraft.item.ItemStack */ object EnvironmentProviderBlocks extends EnvironmentProvider { override def getEnvironment(stack: ItemStack): Class[_] = stack.getItem match { - case block: ItemBlock if block.getBlock != null => + case block: BlockItem if block.getBlock != null => if (isOneOf(block.getBlock, Constants.BlockName.Assembler)) classOf[tileentity.Assembler] else if (isOneOf(block.getBlock, Constants.BlockName.CaseTier1, Constants.BlockName.CaseTier2, Constants.BlockName.CaseTier3, Constants.BlockName.CaseCreative, Constants.BlockName.Microcontroller)) classOf[Machine] else if (isOneOf(block.getBlock, Constants.BlockName.HologramTier1, Constants.BlockName.HologramTier2)) classOf[tileentity.Hologram] diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderDatabase.scala b/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderDatabase.scala index d5216aec00..e8265b661a 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderDatabase.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderDatabase.scala @@ -2,16 +2,16 @@ package li.cil.oc.integration.opencomputers import li.cil.oc.api.driver.InventoryProvider import li.cil.oc.common.inventory.DatabaseInventory -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack object InventoryProviderDatabase extends InventoryProvider { - override def worksWith(stack: ItemStack, player: EntityPlayer): Boolean = DriverUpgradeDatabase.worksWith(stack) + override def worksWith(stack: ItemStack, player: PlayerEntity): Boolean = DriverUpgradeDatabase.worksWith(stack) - override def getInventory(stack: ItemStack, player: EntityPlayer): IInventory = new DatabaseInventory { + override def getInventory(stack: ItemStack, player: PlayerEntity): IInventory = new DatabaseInventory { override def container: ItemStack = stack - override def isUsableByPlayer(player: EntityPlayer): Boolean = player == player + override def stillValid(player: PlayerEntity): Boolean = player == player } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderServer.scala b/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderServer.scala index d7e30f1cd0..d8836e3be7 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderServer.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/InventoryProviderServer.scala @@ -2,14 +2,16 @@ package li.cil.oc.integration.opencomputers import li.cil.oc.api.driver.InventoryProvider import li.cil.oc.common.inventory.ServerInventory -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack object InventoryProviderServer extends InventoryProvider { - override def worksWith(stack: ItemStack, player: EntityPlayer): Boolean = DriverServer.worksWith(stack) + override def worksWith(stack: ItemStack, player: PlayerEntity): Boolean = DriverServer.worksWith(stack) - override def getInventory(stack: ItemStack, player: EntityPlayer): IInventory = new ServerInventory { + override def getInventory(stack: ItemStack, player: PlayerEntity): IInventory = new ServerInventory { override def container: ItemStack = stack + + override def rackSlot = -1 } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala b/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala index 0b63a40f97..4cb60a563b 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/Item.scala @@ -10,7 +10,7 @@ import li.cil.oc.api.internal import li.cil.oc.common.Tier import li.cil.oc.server.driver.Registry import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import scala.annotation.tailrec @@ -18,13 +18,13 @@ trait Item extends DriverItem { def worksWith(stack: ItemStack, host: Class[_ <: EnvironmentHost]): Boolean = worksWith(stack) && !Registry.blacklist.exists { case (blacklistedStack, blacklistedHost) => - stack.isItemEqual(blacklistedStack) && + stack.sameItem(blacklistedStack) && blacklistedHost.exists(_.isAssignableFrom(host)) } override def tier(stack: ItemStack) = Tier.One - override def dataTag(stack: ItemStack): NBTTagCompound = Item.dataTag(stack) + override def dataTag(stack: ItemStack): CompoundNBT = Item.dataTag(stack) protected def isOneOf(stack: ItemStack, items: api.detail.ItemInfo*): Boolean = items.filter(_ != null).contains(api.Items.get(stack)) @@ -46,34 +46,31 @@ trait Item extends DriverItem { } object Item { - def dataTag(stack: ItemStack): NBTTagCompound = { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) + def dataTag(stack: ItemStack): CompoundNBT = { + val nbt = stack.getOrCreateTag + if (!nbt.contains(Settings.namespace + "data")) { + nbt.put(Settings.namespace + "data", new CompoundNBT()) } - val nbt = stack.getTagCompound - if (!nbt.hasKey(Settings.namespace + "data")) { - nbt.setTag(Settings.namespace + "data", new NBTTagCompound()) - } - nbt.getCompoundTag(Settings.namespace + "data") + nbt.getCompound(Settings.namespace + "data") } @tailrec - private def getTag(tagCompound: NBTTagCompound, keys: Array[String]): Option[NBTTagCompound] = { + private def getTag(tagCompound: CompoundNBT, keys: Array[String]): Option[CompoundNBT] = { if (keys.length == 0) Option(tagCompound) - else if (!tagCompound.hasKey(keys(0))) None - else getTag(tagCompound.getCompoundTag(keys(0)), keys.drop(1)) + else if (!tagCompound.contains(keys(0))) None + else getTag(tagCompound.getCompound(keys(0)), keys.drop(1)) } - private def getTag(stack: ItemStack, keys: Array[String]): Option[NBTTagCompound] = { + private def getTag(stack: ItemStack, keys: Array[String]): Option[CompoundNBT] = { if (stack == null || stack.getCount == 0 || stack == ItemStack.EMPTY) None - else if (!stack.hasTagCompound) None - else getTag(stack.getTagCompound, keys) + else if (!stack.hasTag) None + else getTag(stack.getTag, keys) } def address(stack: ItemStack): Option[String] = { val addressKey = "address" getTag(stack, Array(Settings.namespace + "data", "node")) match { - case Some(tag) if tag.hasKey(addressKey) => Option(tag.getString(addressKey)) + case Some(tag) if tag.contains(addressKey) => Option(tag.getString(addressKey)) case _ => None } } diff --git a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala index a36e0d2d63..6804de14c2 100644 --- a/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala +++ b/src/main/scala/li/cil/oc/integration/opencomputers/ModOpenComputers.scala @@ -20,11 +20,9 @@ import li.cil.oc.client.renderer.markdown.segment.render.TextureImageProvider import li.cil.oc.common.EventHandler import li.cil.oc.common.Loot import li.cil.oc.common.SaveHandler -import li.cil.oc.common.asm.SimpleComponentTickHandler import li.cil.oc.common.block.SimpleBlock import li.cil.oc.common.event._ import li.cil.oc.common.item.Analyzer -import li.cil.oc.common.item.Delegator import li.cil.oc.common.item.RedstoneCard import li.cil.oc.common.item.Tablet import li.cil.oc.common.nanomachines.provider.DisintegrationProvider @@ -36,25 +34,26 @@ import li.cil.oc.common.template._ import li.cil.oc.integration.ModProxy import li.cil.oc.integration.Mods import li.cil.oc.integration.util.BundledRedstone -import li.cil.oc.integration.util.ItemBlacklist import li.cil.oc.server.machine.luac.LuaStateFactory import li.cil.oc.server.machine.luac.NativeLua53Architecture import li.cil.oc.server.network.Waypoints import li.cil.oc.server.network.WirelessNetwork import li.cil.oc.util.Color -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import net.minecraftforge.common.ForgeChunkManager +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.api.distmarker.OnlyIn import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.common.world.ForgeChunkManager +import net.minecraftforge.fml.DistExecutor object ModOpenComputers extends ModProxy { override def getMod = Mods.OpenComputers override def initialize() { - ItemBlacklist.apply() - DroneTemplate.register() MicrocontrollerTemplate.register() NavigationUpgradeTemplate.register() @@ -91,27 +90,21 @@ object ModOpenComputers extends ModProxy { api.IMC.registerProgramDiskLabel("opl-flash", "openloader", "Lua 5.2", "Lua 5.3", "LuaJ") api.IMC.registerProgramDiskLabel("oppm", "oppm", "Lua 5.2", "Lua 5.3", "LuaJ") - ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers, ChunkloaderUpgradeHandler) + ForgeChunkManager.setForcedChunkLoadingCallback(OpenComputers.ID, ChunkloaderUpgradeHandler) MinecraftForge.EVENT_BUS.register(EventHandler) MinecraftForge.EVENT_BUS.register(NanomachinesHandler.Common) - MinecraftForge.EVENT_BUS.register(SimpleComponentTickHandler.Instance) MinecraftForge.EVENT_BUS.register(Tablet) - MinecraftForge.EVENT_BUS.register(Analyzer) MinecraftForge.EVENT_BUS.register(AngelUpgradeHandler) - MinecraftForge.EVENT_BUS.register(BlockChangeHandler) MinecraftForge.EVENT_BUS.register(ChunkloaderUpgradeHandler) - MinecraftForge.EVENT_BUS.register(EventHandler) MinecraftForge.EVENT_BUS.register(ExperienceUpgradeHandler) MinecraftForge.EVENT_BUS.register(FileSystemAccessHandler) MinecraftForge.EVENT_BUS.register(HoverBootsHandler) MinecraftForge.EVENT_BUS.register(Loot) - MinecraftForge.EVENT_BUS.register(NanomachinesHandler.Common) MinecraftForge.EVENT_BUS.register(NetworkActivityHandler) MinecraftForge.EVENT_BUS.register(RobotCommonHandler) MinecraftForge.EVENT_BUS.register(SaveHandler) - MinecraftForge.EVENT_BUS.register(Tablet) MinecraftForge.EVENT_BUS.register(Waypoints) MinecraftForge.EVENT_BUS.register(WirelessNetwork) MinecraftForge.EVENT_BUS.register(WirelessNetworkCardHandler) @@ -313,12 +306,20 @@ object ModOpenComputers extends ModProxy { // redstone card availability here, after all other mods were inited. if (BundledRedstone.isAvailable) { OpenComputers.log.info("Found extended redstone mods, enabling tier two redstone card.") - Delegator.subItem(api.Items.get(Constants.ItemName.RedstoneCardTier2).createItemStack(1)) match { - case Some(redstone: RedstoneCard) => redstone.showInItemList = true - case _ => - } + ModOpenComputers.hasRedstoneCardT2 = true } + api.Nanomachines.addProvider(DisintegrationProvider) + api.Nanomachines.addProvider(HungryProvider) + api.Nanomachines.addProvider(ParticleProvider) + api.Nanomachines.addProvider(PotionProvider) + api.Nanomachines.addProvider(MagnetProvider) + + DistExecutor.runWhenOn(Dist.CLIENT, () => () => initializeClient()) + } + + @OnlyIn(Dist.CLIENT) + private def initializeClient() { api.Manual.addProvider(DefinitionPathProvider) api.Manual.addProvider(new ResourceContentProvider(Settings.resourceDomain, "doc/")) api.Manual.addProvider("", TextureImageProvider) @@ -329,17 +330,13 @@ object ModOpenComputers extends ModProxy { api.Manual.addTab(new TextureTabIconRenderer(Textures.GUI.ManualHome), "oc:gui.Manual.Home", "%LANGUAGE%/index.md") api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("case1").createItemStack(1)), "oc:gui.Manual.Blocks", "%LANGUAGE%/block/index.md") api.Manual.addTab(new ItemStackTabIconRenderer(api.Items.get("cpu1").createItemStack(1)), "oc:gui.Manual.Items", "%LANGUAGE%/item/index.md") - - api.Nanomachines.addProvider(DisintegrationProvider) - api.Nanomachines.addProvider(HungryProvider) - api.Nanomachines.addProvider(ParticleProvider) - api.Nanomachines.addProvider(PotionProvider) - api.Nanomachines.addProvider(MagnetProvider) } - def useWrench(player: EntityPlayer, pos: BlockPos, changeDurability: Boolean): Boolean = { - player.getHeldItemMainhand.getItem match { - case wrench: Wrench => wrench.useWrenchOnBlock(player, player.getEntityWorld, pos, !changeDurability) + protected[oc] var hasRedstoneCardT2 = false + + def useWrench(player: PlayerEntity, pos: BlockPos, changeDurability: Boolean): Boolean = { + player.getItemInHand(Hand.MAIN_HAND).getItem match { + case wrench: Wrench => wrench.useWrenchOnBlock(player, player.level, pos, !changeDurability) case _ => false } } diff --git a/src/main/scala/li/cil/oc/integration/projectred/BundledProviderProjectRed.scala b/src/main/scala/li/cil/oc/integration/projectred/BundledProviderProjectRed.scala new file mode 100644 index 0000000000..d453ae0eb8 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/projectred/BundledProviderProjectRed.scala @@ -0,0 +1,23 @@ +package li.cil.oc.integration.projectred + +import li.cil.oc.common.tileentity.traits.BundledRedstoneAware +import mrtjp.projectred.api.IBundledTileInteraction +import mrtjp.projectred.api.ProjectRedAPI +import net.minecraft.util.Direction +import net.minecraft.util.math.BlockPos +import net.minecraft.world.World + +object BundledProviderProjectRed extends IBundledTileInteraction { + def install(): Unit = ProjectRedAPI.transmissionAPI.registerBundledTileInteraction(this) + + override def isValidInteractionFor(world: World, pos: BlockPos, side: Direction) = + world.getBlockEntity(pos).isInstanceOf[BundledRedstoneAware] + + override def canConnectBundled(world: World, pos: BlockPos, side: Direction): Boolean = + world.getBlockEntity(pos).asInstanceOf[BundledRedstoneAware].isOutputEnabled + + override def getBundledSignal(world: World, pos: BlockPos, side: Direction): Array[Byte] = { + val tileEntity = world.getBlockEntity(pos).asInstanceOf[BundledRedstoneAware] + tileEntity.getBundledOutput(side).map(value => math.min(math.max(value, 0), 255).toByte) + } +} diff --git a/src/main/scala/li/cil/oc/integration/projectred/EventHandlerProjectRed.scala b/src/main/scala/li/cil/oc/integration/projectred/EventHandlerProjectRed.scala index 63ec0c5165..2707370e7e 100644 --- a/src/main/scala/li/cil/oc/integration/projectred/EventHandlerProjectRed.scala +++ b/src/main/scala/li/cil/oc/integration/projectred/EventHandlerProjectRed.scala @@ -1,13 +1,14 @@ package li.cil.oc.integration.projectred import mrtjp.projectred.api.IScrewdriver -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos object EventHandlerProjectRed { - def useWrench(player: EntityPlayer, pos: BlockPos, changeDurability: Boolean): Boolean = { - val stack = player.getHeldItemMainhand + def useWrench(player: PlayerEntity, pos: BlockPos, changeDurability: Boolean): Boolean = { + val stack = player.getItemInHand(Hand.MAIN_HAND) stack.getItem match { case wrench: IScrewdriver => if (changeDurability) { diff --git a/src/main/scala/li/cil/oc/integration/projectred/ModProjectRed.scala b/src/main/scala/li/cil/oc/integration/projectred/ModProjectRed.scala index d5a92c7cc8..efecdc915e 100644 --- a/src/main/scala/li/cil/oc/integration/projectred/ModProjectRed.scala +++ b/src/main/scala/li/cil/oc/integration/projectred/ModProjectRed.scala @@ -7,7 +7,8 @@ import li.cil.oc.integration.util.BundledRedstone import li.cil.oc.integration.util.BundledRedstone.RedstoneProvider import li.cil.oc.util.BlockPosition import mrtjp.projectred.api.ProjectRedAPI -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.world.World object ModProjectRed extends ModProxy with RedstoneProvider { override def getMod = Mods.ProjectRedTransmission @@ -17,11 +18,12 @@ object ModProjectRed extends ModProxy with RedstoneProvider { api.IMC.registerWrenchToolCheck("li.cil.oc.integration.projectred.EventHandlerProjectRed.isWrench") BundledRedstone.addProvider(this) + BundledProviderProjectRed.install() } - override def computeInput(pos: BlockPosition, side: EnumFacing): Int = 0 + override def computeInput(pos: BlockPosition, side: Direction): Int = 0 - def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int] = { + def computeBundledInput(pos: BlockPosition, side: Direction): Array[Int] = { Option(ProjectRedAPI.transmissionAPI.getBundledInput(pos.world.get, pos.toBlockPos, side)). fold(null: Array[Int])(_.map(_ & 0xFF)) } diff --git a/src/main/scala/li/cil/oc/integration/thaumcraft/ConverterThaumcraftItems.scala b/src/main/scala/li/cil/oc/integration/thaumcraft/ConverterThaumcraftItems.scala deleted file mode 100644 index 6adf8baffc..0000000000 --- a/src/main/scala/li/cil/oc/integration/thaumcraft/ConverterThaumcraftItems.scala +++ /dev/null @@ -1,47 +0,0 @@ -package li.cil.oc.integration.thaumcraft - -import java.util - -import li.cil.oc.api.driver.Converter -import net.minecraft.item.{Item, ItemStack} -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.common.util.Constants.NBT - -import scala.collection.convert.WrapAsScala._ -import scala.collection.mutable - -object ConverterThaumcraftItems extends Converter { - override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]): Unit = value match { - case stack: ItemStack => - val name = Item.REGISTRY.getNameForObject(stack.getItem).toString - - // Handle essentia/vis contents for Thaumcraft jars, phials, and crystals - if ((name == "thaumcraft:jar_normal") || - (name == "thaumcraft:jar_void") || - (name == "thaumcraft:phial") || - (name == "thaumcraft:crystal_essence")) { - if (stack.hasTagCompound && - stack.getTagCompound.hasKey("Aspects", NBT.TAG_LIST)) { - val aspects = mutable.ArrayBuffer.empty[mutable.Map[String, Any]] - val nbtAspects = stack.getTagCompound.getTagList("Aspects", NBT.TAG_COMPOUND).map { - case tag: NBTTagCompound => tag - } - for (nbtAspect <- nbtAspects) { - val key = nbtAspect.getString("key") - val amount = nbtAspect.getInteger("amount") - val aspect = mutable.Map[String, Any]( - "aspect" -> key, - "amount" -> amount - ) - aspects += aspect - } - output += "aspects" -> aspects - } - if (stack.hasTagCompound && stack.getTagCompound.hasKey("AspectFilter", NBT.TAG_STRING)) { - output += "aspectFilter" -> stack.getTagCompound.getString("AspectFilter") - } - } - - case _ => - } -} diff --git a/src/main/scala/li/cil/oc/integration/thaumcraft/ModThaumcraft.scala b/src/main/scala/li/cil/oc/integration/thaumcraft/ModThaumcraft.scala deleted file mode 100644 index 4e1954adfc..0000000000 --- a/src/main/scala/li/cil/oc/integration/thaumcraft/ModThaumcraft.scala +++ /dev/null @@ -1,13 +0,0 @@ -package li.cil.oc.integration.thaumcraft - -import li.cil.oc.api.Driver -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods - -object ModThaumcraft extends ModProxy { - override def getMod: Mods.ModBase = Mods.Thaumcraft - - override def initialize() { - Driver.add(ConverterThaumcraftItems) - } -} diff --git a/src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala b/src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala index ee83aef8c8..83cc319bdf 100644 --- a/src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala +++ b/src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala @@ -2,11 +2,20 @@ package li.cil.oc.integration.tis3d import li.cil.oc.integration.ModProxy import li.cil.oc.integration.Mods +import li.cil.tis3d.api.serial.SerialInterfaceProvider +import net.minecraftforge.event.RegistryEvent +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.scorge.lang.ScorgeModLoadingContext object ModTIS3D extends ModProxy { override def getMod = Mods.TIS3D - override def initialize(): Unit = { - SerialInterfaceProviderAdapter.init() + @SubscribeEvent + def registerSerialInterfaceProviders(e: RegistryEvent.Register[SerialInterfaceProvider]) { + e.getRegistry.register(SerialInterfaceProviderAdapter) + } + + override def preInitialize(): Unit = { + ScorgeModLoadingContext.get.getModEventBus.register(this) } } diff --git a/src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala b/src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala index 74737fdd61..f17b89a002 100644 --- a/src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala +++ b/src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala @@ -1,5 +1,8 @@ package li.cil.oc.integration.tis3d +import java.util.Optional + +import li.cil.oc.OpenComputers import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.internal.Adapter @@ -11,33 +14,30 @@ import li.cil.oc.api.network.Message import li.cil.oc.api.network.Node import li.cil.oc.api.network.Visibility import li.cil.oc.util.ResultWrapper.result -import li.cil.tis3d.api.ManualAPI -import li.cil.tis3d.api.SerialAPI -import li.cil.tis3d.api.prefab.manual.ResourceContentProvider import li.cil.tis3d.api.serial.SerialInterface import li.cil.tis3d.api.serial.SerialInterfaceProvider import li.cil.tis3d.api.serial.SerialProtocolDocumentationReference -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import li.cil.tis3d.common.provider.SerialInterfaceProviders +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World +import net.minecraftforge.registries.ForgeRegistryEntry import scala.collection.mutable -object SerialInterfaceProviderAdapter extends SerialInterfaceProvider { - def init(): Unit = { - ManualAPI.addProvider(new ResourceContentProvider(Settings.resourceDomain, "doc/tis3d/")) - SerialAPI.addProvider(this) - } +object SerialInterfaceProviderAdapter extends ForgeRegistryEntry[SerialInterfaceProvider] with SerialInterfaceProvider { + setRegistryName(OpenComputers.ID, "serial_port") - override def getDocumentationReference = new SerialProtocolDocumentationReference("OpenComputers Adapter", "protocols/opencomputersadapter.md") + override def getDocumentationReference = Optional.of(new SerialProtocolDocumentationReference(new StringTextComponent("OpenComputers Adapter"), "protocols/opencomputersadapter.md")) - override def worksWith(world: World, pos: BlockPos, side: EnumFacing): Boolean = world.getTileEntity(pos).isInstanceOf[Adapter] + override def matches(world: World, pos: BlockPos, side: Direction): Boolean = world.getBlockEntity(pos).isInstanceOf[Adapter] - override def interfaceFor(world: World, pos: BlockPos, side: EnumFacing): SerialInterface = new SerialInterfaceAdapter(world.getTileEntity(pos).asInstanceOf[Adapter]) + override def getInterface(world: World, pos: BlockPos, side: Direction): Optional[SerialInterface] = Optional.of(new SerialInterfaceAdapter(world.getBlockEntity(pos).asInstanceOf[Adapter])) - override def isValid(world: World, pos: BlockPos, side: EnumFacing, serialInterface: SerialInterface): Boolean = serialInterface match { - case adapter: SerialInterfaceAdapter => adapter.tileEntity == world.getTileEntity(pos) + override def stillValid(world: World, pos: BlockPos, side: Direction, serialInterface: SerialInterface): Boolean = serialInterface match { + case adapter: SerialInterfaceAdapter => adapter.tileEntity == world.getBlockEntity(pos) case _ => false } @@ -107,8 +107,8 @@ object SerialInterfaceProviderAdapter extends SerialInterfaceProvider { }) } - override def readFromNBT(nbt: NBTTagCompound): Unit = { - node.load(nbt) + override def readFromNBT(nbt: CompoundNBT): Unit = { + node.loadData(nbt) writeBuffer.clear() writeBuffer ++= nbt.getIntArray("writeBuffer").map(_.toShort) @@ -117,12 +117,12 @@ object SerialInterfaceProviderAdapter extends SerialInterfaceProvider { isReading = nbt.getBoolean("isReading") } - override def writeToNBT(nbt: NBTTagCompound): Unit = { - node.save(nbt) + override def writeToNBT(nbt: CompoundNBT): Unit = { + node.saveData(nbt) - nbt.setIntArray("writeBuffer", writeBuffer.toArray.map(_.toInt)) - nbt.setIntArray("readBuffer", readBuffer.toArray.map(_.toInt)) - nbt.setBoolean("isReading", isReading) + nbt.putIntArray("writeBuffer", writeBuffer.toArray.map(_.toInt)) + nbt.putIntArray("readBuffer", readBuffer.toArray.map(_.toInt)) + nbt.putBoolean("isReading", isReading) } private def ensureConnected(): Unit = { diff --git a/src/main/scala/li/cil/oc/integration/util/BundledRedstone.scala b/src/main/scala/li/cil/oc/integration/util/BundledRedstone.scala index d133bd8f5a..d4862511b8 100644 --- a/src/main/scala/li/cil/oc/integration/util/BundledRedstone.scala +++ b/src/main/scala/li/cil/oc/integration/util/BundledRedstone.scala @@ -3,7 +3,7 @@ package li.cil.oc.integration.util import li.cil.oc.integration.Mods import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import scala.collection.mutable @@ -14,25 +14,25 @@ object BundledRedstone { def isAvailable = providers.nonEmpty - def computeInput(pos: BlockPosition, side: EnumFacing): Int = { + def computeInput(pos: BlockPosition, side: Direction): Int = { if (pos.world.get.blockExists(pos.offset(side))) providers.map(_.computeInput(pos, side)).padTo(1, 0).max else 0 } - def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int] = { + def computeBundledInput(pos: BlockPosition, side: Direction): Array[Int] = { if (pos.world.get.blockExists(pos.offset(side))) { val inputs = providers.map(_.computeBundledInput(pos, side)).filter(_ != null) if (inputs.isEmpty) null - else inputs.reduce((a, b) => (a, b).zipped.map((l, r) => math.max(l, r))) + else inputs.reduce((a, b) => a.lazyZip(b).map((l, r) => math.max(l, r))) } else null } trait RedstoneProvider { - def computeInput(pos: BlockPosition, side: EnumFacing): Int + def computeInput(pos: BlockPosition, side: Direction): Int - def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int] + def computeBundledInput(pos: BlockPosition, side: Direction): Array[Int] } } diff --git a/src/main/scala/li/cil/oc/integration/util/DamageSourceWithRandomCause.scala b/src/main/scala/li/cil/oc/integration/util/DamageSourceWithRandomCause.scala index 4afb8ff14f..9128f7b4be 100644 --- a/src/main/scala/li/cil/oc/integration/util/DamageSourceWithRandomCause.scala +++ b/src/main/scala/li/cil/oc/integration/util/DamageSourceWithRandomCause.scala @@ -1,19 +1,19 @@ package li.cil.oc.integration.util import net.minecraft.client.resources.I18n -import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.LivingEntity import net.minecraft.util.DamageSource import net.minecraft.util.text.ITextComponent -import net.minecraft.util.text.TextComponentTranslation +import net.minecraft.util.text.TranslationTextComponent class DamageSourceWithRandomCause(name: String, numCauses: Int) extends DamageSource(name) { - override def getDeathMessage(damagee: EntityLivingBase): ITextComponent = { - val damager = damagee.getAttackingEntity - val format = "death.attack." + damageType + "." + (damagee.world.rand.nextInt(numCauses) + 1) + override def getLocalizedDeathMessage(damagee: LivingEntity): ITextComponent = { + val damager = damagee.getKillCredit + val format = "death.attack." + msgId + "." + (damagee.level.random.nextInt(numCauses) + 1) val withCauseFormat = format + ".player" - if (damager != null && I18n.hasKey(withCauseFormat)) - new TextComponentTranslation(withCauseFormat, damagee.getDisplayName, damager.getDisplayName) + if (damager != null && I18n.exists(withCauseFormat)) + new TranslationTextComponent(withCauseFormat, damagee.getDisplayName, damager.getDisplayName) else - new TextComponentTranslation(format, damagee.getDisplayName) + new TranslationTextComponent(format, damagee.getDisplayName) } } diff --git a/src/main/scala/li/cil/oc/integration/util/ItemBlacklist.scala b/src/main/scala/li/cil/oc/integration/util/ItemBlacklist.scala deleted file mode 100644 index 6c42f04a4b..0000000000 --- a/src/main/scala/li/cil/oc/integration/util/ItemBlacklist.scala +++ /dev/null @@ -1,27 +0,0 @@ -package li.cil.oc.integration.util - -import li.cil.oc.common.item.traits.Delegate -import net.minecraft.block.Block -import net.minecraft.item.ItemStack - -import scala.collection.mutable - -object ItemBlacklist { - // Lazily evaluated stacks to avoid creating stacks with unregistered items/blocks. - val hiddenItems = mutable.Set.empty[() => ItemStack] - - // List of consumers for item stacks (blacklisting for NEI and JEI). - val consumers = mutable.Set.empty[ItemStack => Unit] - - def hide(block: Block): Unit = hiddenItems += (() => new ItemStack(block)) - - def hide(item: Delegate): Unit = hiddenItems += (() => item.createItemStack()) - - def apply(): Unit = { - for (consumer <- consumers) { - for (stack <- hiddenItems) { - consumer(stack()) - } - } - } -} diff --git a/src/main/scala/li/cil/oc/integration/util/ItemSearch.scala b/src/main/scala/li/cil/oc/integration/util/ItemSearch.scala index 8980cf2627..7326080ffb 100644 --- a/src/main/scala/li/cil/oc/integration/util/ItemSearch.scala +++ b/src/main/scala/li/cil/oc/integration/util/ItemSearch.scala @@ -2,14 +2,14 @@ package li.cil.oc.integration.util import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ -import net.minecraft.client.gui.inventory.GuiContainer +import net.minecraft.client.gui.screen.inventory.ContainerScreen import scala.collection.mutable object ItemSearch { val focusedInput = mutable.Set.empty[() => Boolean] - val stackFocusing = mutable.Set.empty[(GuiContainer, Int, Int) => StackOption] + val stackFocusing = mutable.Set.empty[(ContainerScreen[_], Int, Int) => StackOption] def isInputFocused: Boolean = { for (f <- focusedInput) { @@ -18,7 +18,7 @@ object ItemSearch { false } - def hoveredStack(container: GuiContainer, mouseX: Int, mouseY: Int): StackOption = { + def hoveredStack(container: ContainerScreen[_], mouseX: Int, mouseY: Int): StackOption = { for (f <- stackFocusing) { f(container, mouseX, mouseY).foreach(stack => return StackOption(stack)) } diff --git a/src/main/scala/li/cil/oc/integration/util/Wrench.scala b/src/main/scala/li/cil/oc/integration/util/Wrench.scala index d3f50a107c..b0adc1b285 100644 --- a/src/main/scala/li/cil/oc/integration/util/Wrench.scala +++ b/src/main/scala/li/cil/oc/integration/util/Wrench.scala @@ -3,8 +3,9 @@ package li.cil.oc.integration.util import java.lang.reflect.Method import li.cil.oc.common.IMC -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos import scala.collection.mutable @@ -19,9 +20,9 @@ object Wrench { def isWrench(stack: ItemStack): Boolean = !stack.isEmpty && checks.exists(IMC.tryInvokeStatic(_, stack)(false)) - def holdsApplicableWrench(player: EntityPlayer, position: BlockPos): Boolean = - !player.getHeldItemMainhand.isEmpty && usages.exists(IMC.tryInvokeStatic(_, player, position, java.lang.Boolean.FALSE)(false)) + def holdsApplicableWrench(player: PlayerEntity, position: BlockPos): Boolean = + !player.getItemInHand(Hand.MAIN_HAND).isEmpty && usages.exists(IMC.tryInvokeStatic(_, player, position, java.lang.Boolean.FALSE)(false)) - def wrenchUsed(player: EntityPlayer, position: BlockPos): Unit = - if (!player.getHeldItemMainhand.isEmpty) usages.foreach(IMC.tryInvokeStaticVoid(_, player, position, java.lang.Boolean.TRUE)) + def wrenchUsed(player: PlayerEntity, position: BlockPos): Unit = + if (!player.getItemInHand(Hand.MAIN_HAND).isEmpty) usages.foreach(IMC.tryInvokeStaticVoid(_, player, position, java.lang.Boolean.TRUE)) } diff --git a/src/main/scala/li/cil/oc/integration/waila/BlockDataProvider.scala b/src/main/scala/li/cil/oc/integration/waila/BlockDataProvider.scala index bd2b7bc252..cc8b8f3493 100644 --- a/src/main/scala/li/cil/oc/integration/waila/BlockDataProvider.scala +++ b/src/main/scala/li/cil/oc/integration/waila/BlockDataProvider.scala @@ -14,47 +14,54 @@ import li.cil.oc.common.tileentity.traits.NotAnalyzable import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.StackOption.SomeStack import mcp.mobius.waila.api._ -import net.minecraft.entity.player.EntityPlayerMP +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagString +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.StringNBT import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.BlockPos +import net.minecraft.util.Direction +import net.minecraft.util.ResourceLocation +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World import net.minecraftforge.common.util.Constants.NBT -object BlockDataProvider extends IWailaDataProvider { - val ConfigAddress = "oc.address" - val ConfigEnergy = "oc.energy" - val ConfigComponentName = "oc.componentName" +@WailaPlugin +class BlockDataProvider extends IWailaPlugin { + def register(registrar: IRegistrar) = BlockDataProvider.register(registrar) +} + +object BlockDataProvider extends IServerDataProvider[TileEntity] with IComponentProvider { + val ConfigAddress = new ResourceLocation(OpenComputers.ID, "oc.address") + val ConfigEnergy = new ResourceLocation(OpenComputers.ID, "oc.energy") + val ConfigComponentName = new ResourceLocation(OpenComputers.ID, "oc.componentname") - def init(registrar: IWailaRegistrar) { - registrar.registerBodyProvider(BlockDataProvider, classOf[SimpleBlock]) + private def register(registrar: IRegistrar) { + registrar.registerComponentProvider(this, TooltipPosition.BODY, classOf[SimpleBlock]) - registrar.registerNBTProvider(this, classOf[li.cil.oc.api.network.Environment]) - registrar.registerNBTProvider(this, classOf[li.cil.oc.api.network.SidedEnvironment]) + registrar.registerBlockDataProvider(this, classOf[li.cil.oc.api.network.Environment]) + registrar.registerBlockDataProvider(this, classOf[li.cil.oc.api.network.SidedEnvironment]) - registrar.addConfig(OpenComputers.Name, ConfigAddress) - registrar.addConfig(OpenComputers.Name, ConfigEnergy) - registrar.addConfig(OpenComputers.Name, ConfigComponentName) + registrar.addConfig(ConfigAddress, true) + registrar.addConfig(ConfigEnergy, true) + registrar.addConfig(ConfigComponentName, true) } - override def getNBTData(player: EntityPlayerMP, tileEntity: TileEntity, tag: NBTTagCompound, world: World, pos: BlockPos): NBTTagCompound = { - def writeNode(node: Node, tag: NBTTagCompound) = { + override def appendServerData(tag: CompoundNBT, player: ServerPlayerEntity, world: World, tileEntity: TileEntity): Unit = { + def writeNode(node: Node, tag: CompoundNBT) = { if (node != null && node.reachability != Visibility.None && !tileEntity.isInstanceOf[NotAnalyzable]) { if (node.address != null) { - tag.setString("address", node.address) + tag.putString("address", node.address) } node match { case connector: Connector => - tag.setInteger("buffer", connector.localBuffer.toInt) - tag.setInteger("bufferSize", connector.localBufferSize.toInt) + tag.putInt("buffer", connector.localBuffer.toInt) + tag.putInt("bufferSize", connector.localBufferSize.toInt) case _ => } node match { case component: Component => - tag.setString("componentName", component.name) + tag.putString("componentName", component.name) case _ => } } @@ -63,9 +70,9 @@ object BlockDataProvider extends IWailaDataProvider { tileEntity match { case te: li.cil.oc.api.network.SidedEnvironment => - tag.setNewTagList("nodes", EnumFacing.values. + tag.setNewTagList("nodes", Direction.values. map(te.sidedNode). - map(writeNode(_, new NBTTagCompound()))) + map(writeNode(_, new CompoundNBT()))) case te: li.cil.oc.api.network.Environment => writeNode(te.node, tag) case _ => @@ -73,14 +80,14 @@ object BlockDataProvider extends IWailaDataProvider { // Override sided info (show info on all sides). def ignoreSidedness(node: Node): Unit = { - tag.removeTag("nodes") - val nodeTag = writeNode(node, new NBTTagCompound()) - tag.setNewTagList("nodes", EnumFacing.values.map(_ => nodeTag)) + tag.remove("nodes") + val nodeTag = writeNode(node, new CompoundNBT()) + tag.setNewTagList("nodes", Direction.values.map(_ => nodeTag)) } tileEntity match { case te: tileentity.Relay => - tag.setDouble("signalStrength", te.strength) + tag.putDouble("signalStrength", te.strength) // this might be called by waila before the components have finished loading, thus the addresses may be null tag.setNewTagList("addresses", stringIterableToNbt(te.componentNodes.collect { case n if n.address != null => n @@ -88,110 +95,102 @@ object BlockDataProvider extends IWailaDataProvider { case te: tileentity.Assembler => ignoreSidedness(te.node) if (te.isAssembling) { - tag.setDouble("progress", te.progress) - tag.setInteger("timeRemaining", te.timeRemaining) + tag.putDouble("progress", te.progress) + tag.putInt("timeRemaining", te.timeRemaining) te.output match { - case SomeStack(output) => tag.setString("output", output.getUnlocalizedName) + case SomeStack(output) => tag.putString("output", output.getDescriptionId) case _ => // Huh... } } case te: tileentity.Charger => - tag.setDouble("chargeSpeed", te.chargeSpeed) + tag.putDouble("chargeSpeed", te.chargeSpeed) case te: tileentity.DiskDrive => // Override address with file system address. - tag.removeTag("address") + tag.remove("address") te.filesystemNode.foreach(writeNode(_, tag)) case te: tileentity.Hologram => ignoreSidedness(te.node) case te: tileentity.Keyboard => ignoreSidedness(te.node) case te: tileentity.Screen => ignoreSidedness(te.node) case te: tileentity.Rack => - tag.removeTag("nodes") + tag.remove("nodes") //tag.setNewTagList("servers", stringIterableToNbt(te.servers.map(_.fold("")(_.node.address)))) - //tag.setByteArray("sideIndexes", EnumFacing.values.map(side => te.sides.indexWhere(_.contains(side))).map(_.toByte)) + //tag.putByteArray("sideIndexes", Direction.values.map(side => te.sides.indexWhere(_.contains(side))).map(_.toByte)) // TODO case _ => } - - tag } - override def getWailaBody(stack: ItemStack, tooltip: util.List[String], accessor: IWailaDataAccessor, config: IWailaConfigHandler): util.List[String] = { - val tag = accessor.getNBTData - if (tag == null || tag.hasNoTags) return tooltip + override def appendBody(tooltip: util.List[ITextComponent], accessor: IDataAccessor, config: IPluginConfig): Unit = { + val tag = accessor.getServerData + if (tag == null || tag.isEmpty) return accessor.getTileEntity match { case _: tileentity.Relay => - val address = tag.getTagList("addresses", NBT.TAG_STRING).getStringTagAt(accessor.getSide.ordinal) + val address = tag.getList("addresses", NBT.TAG_STRING).getString(accessor.getSide.ordinal) val signalStrength = tag.getDouble("signalStrength") - if (config.getConfig(ConfigAddress)) { - tooltip.add(Localization.Analyzer.Address(address).getUnformattedText) + if (config.get(ConfigAddress)) { + tooltip.add(Localization.Analyzer.Address(address)) } - tooltip.add(Localization.Analyzer.WirelessStrength(signalStrength).getUnformattedText) + tooltip.add(Localization.Analyzer.WirelessStrength(signalStrength)) case _: tileentity.Assembler => - if (tag.hasKey("progress")) { + if (tag.contains("progress")) { val progress = tag.getDouble("progress") - val timeRemaining = formatTime(tag.getInteger("timeRemaining")) - tooltip.add(Localization.Assembler.Progress(progress, timeRemaining)) - if (tag.hasKey("output")) { + val timeRemaining = formatTime(tag.getInt("timeRemaining")) + tooltip.add(new StringTextComponent(Localization.Assembler.Progress(progress, timeRemaining))) + if (tag.contains("output")) { val output = tag.getString("output") - tooltip.add("Building: " + Localization.localizeImmediately(output)) + tooltip.add(new StringTextComponent("Building: " + Localization.localizeImmediately(output))) } } case _: tileentity.Charger => val chargeSpeed = tag.getDouble("chargeSpeed") - tooltip.add(Localization.Analyzer.ChargerSpeed(chargeSpeed).getUnformattedText) + tooltip.add(Localization.Analyzer.ChargerSpeed(chargeSpeed)) case te: tileentity.Rack => -// val servers = tag.getTagList("servers", NBT.TAG_STRING).map((t: NBTTagString) => t.getString).toArray -// val hitPos = accessor.getMOP.hitVec +// val servers = tag.getList("servers", NBT.TAG_STRING).map((t: StringNBT) => t.getAsString).toArray +// val hitPos = accessor.getMOP.getLocation // val address = te.slotAt(accessor.getSide, (hitPos.xCoord - accessor.getMOP.getBlockPos.getX).toFloat, (hitPos.yCoord - accessor.getMOP.getBlockPos.getY).toFloat, (hitPos.zCoord - accessor.getMOP.getBlockPos.getZ).toFloat) match { // case Some(slot) => servers(slot) // case _ => tag.getByteArray("sideIndexes").map(index => if (index >= 0) servers(index) else "").apply(te.toLocal(accessor.getSide).ordinal) // } -// if (address.nonEmpty && config.getConfig(ConfigAddress)) { -// tooltip.add(Localization.Analyzer.Address(address).getUnformattedText) +// if (address.nonEmpty && config.get(ConfigAddress)) { +// tooltip.add(Localization.Analyzer.Address(address)) // } // TODO case _ => } - def readNode(tag: NBTTagCompound) = { - if (config.getConfig(ConfigAddress) && tag.hasKey("address")) { + def readNode(tag: CompoundNBT) = { + if (config.get(ConfigAddress) && tag.contains("address")) { val address = tag.getString("address") if (address.nonEmpty) { - tooltip.add(Localization.Analyzer.Address(address).getUnformattedText) + tooltip.add(Localization.Analyzer.Address(address)) } } - if (config.getConfig(ConfigEnergy) && tag.hasKey("buffer") && tag.hasKey("bufferSize")) { - val buffer = tag.getInteger("buffer") - val bufferSize = tag.getInteger("bufferSize") + if (config.get(ConfigEnergy) && tag.contains("buffer") && tag.contains("bufferSize")) { + val buffer = tag.getInt("buffer") + val bufferSize = tag.getInt("bufferSize") if (bufferSize > 0) { - tooltip.add(Localization.Analyzer.StoredEnergy(s"$buffer/$bufferSize").getUnformattedText) + tooltip.add(Localization.Analyzer.StoredEnergy(s"$buffer/$bufferSize")) } } - if (config.getConfig(ConfigComponentName) && tag.hasKey("componentName")) { + if (config.get(ConfigComponentName) && tag.contains("componentName")) { val componentName = tag.getString("componentName") if (componentName.nonEmpty) { - tooltip.add(Localization.Analyzer.ComponentName(componentName).getUnformattedText) + tooltip.add(Localization.Analyzer.ComponentName(componentName)) } } } accessor.getTileEntity match { case te: li.cil.oc.api.network.SidedEnvironment => - readNode(tag.getTagList("nodes", NBT.TAG_COMPOUND).getCompoundTagAt(accessor.getSide.ordinal)) + readNode(tag.getList("nodes", NBT.TAG_COMPOUND).getCompound(accessor.getSide.ordinal)) case te: li.cil.oc.api.network.Environment => readNode(tag) case _ => } - - tooltip } - override def getWailaStack(accessor: IWailaDataAccessor, config: IWailaConfigHandler) = accessor.getStack - - override def getWailaHead(stack: ItemStack, tooltip: util.List[String], accessor: IWailaDataAccessor, config: IWailaConfigHandler): util.List[String] = tooltip - - override def getWailaTail(stack: ItemStack, tooltip: util.List[String], accessor: IWailaDataAccessor, config: IWailaConfigHandler): util.List[String] = tooltip + override def getStack(accessor: IDataAccessor, config: IPluginConfig) = accessor.getStack private def formatTime(seconds: Int) = { // Assembly times should not / rarely exceed one hour, so this is good enough. diff --git a/src/main/scala/li/cil/oc/integration/waila/ModWaila.scala b/src/main/scala/li/cil/oc/integration/waila/ModWaila.scala deleted file mode 100644 index cf7dd63183..0000000000 --- a/src/main/scala/li/cil/oc/integration/waila/ModWaila.scala +++ /dev/null @@ -1,13 +0,0 @@ -package li.cil.oc.integration.waila - -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods -import net.minecraftforge.fml.common.event.FMLInterModComms - -object ModWaila extends ModProxy { - override def getMod = Mods.Waila - - override def initialize() { - FMLInterModComms.sendMessage(Mods.IDs.Waila, "register", "li.cil.oc.integration.waila.BlockDataProvider.init") - } -} diff --git a/src/main/scala/li/cil/oc/integration/wrcbe/ModWRCBE.scala b/src/main/scala/li/cil/oc/integration/wrcbe/ModWRCBE.scala deleted file mode 100644 index 4bf9de59d8..0000000000 --- a/src/main/scala/li/cil/oc/integration/wrcbe/ModWRCBE.scala +++ /dev/null @@ -1,13 +0,0 @@ -package li.cil.oc.integration.wrcbe - -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods -import li.cil.oc.integration.util.WirelessRedstone - -object ModWRCBE extends ModProxy { - override def getMod: Mods.SimpleMod = Mods.WirelessRedstoneCBE - - override def initialize() { - WirelessRedstone.systems += WirelessRedstoneCBE - } -} diff --git a/src/main/scala/li/cil/oc/integration/wrcbe/WirelessRedstoneCBE.scala b/src/main/scala/li/cil/oc/integration/wrcbe/WirelessRedstoneCBE.scala deleted file mode 100644 index 5ee787d48c..0000000000 --- a/src/main/scala/li/cil/oc/integration/wrcbe/WirelessRedstoneCBE.scala +++ /dev/null @@ -1,43 +0,0 @@ -package li.cil.oc.integration.wrcbe - -import codechicken.wirelessredstone.manager.RedstoneEther -import li.cil.oc.integration.util.WirelessRedstone.WirelessRedstoneSystem -import li.cil.oc.server.component.RedstoneWireless - -import scala.language.reflectiveCalls - -object WirelessRedstoneCBE extends WirelessRedstoneSystem { - def addTransmitter(rs: RedstoneWireless) { - if (rs.wirelessOutput && rs.wirelessFrequency > 0) { - RedstoneEther.server.addTransmittingDevice(rs) - } - } - - def removeTransmitter(rs: RedstoneWireless) { - if (rs.wirelessFrequency > 0) { - RedstoneEther.server.removeTransmittingDevice(rs) - } - } - - def addReceiver(rs: RedstoneWireless) { - RedstoneEther.server.addReceivingDevice(rs) - if (rs.wirelessFrequency > 0) { - rs.wirelessInput = RedstoneEther.server.isFreqOn(rs.wirelessFrequency) - } - } - - def removeReceiver(rs: RedstoneWireless) { - RedstoneEther.server.removeReceivingDevice(rs) - } - - def updateOutput(rs: RedstoneWireless) { - if (rs.wirelessOutput) { - addTransmitter(rs) - } - else { - removeTransmitter(rs) - } - } - - def getInput(rs: RedstoneWireless): Boolean = rs.wirelessInput -} diff --git a/src/main/scala/li/cil/oc/server/ComponentTracker.scala b/src/main/scala/li/cil/oc/server/ComponentTracker.scala index 0071dace49..a833ff2f0b 100644 --- a/src/main/scala/li/cil/oc/server/ComponentTracker.scala +++ b/src/main/scala/li/cil/oc/server/ComponentTracker.scala @@ -4,5 +4,5 @@ import li.cil.oc.common import net.minecraft.world.World object ComponentTracker extends common.ComponentTracker { - override protected def clear(world: World) = if (!world.isRemote) super.clear(world) + override protected def clear(world: World) = if (!world.isClientSide) super.clear(world) } diff --git a/src/main/scala/li/cil/oc/server/GuiHandler.scala b/src/main/scala/li/cil/oc/server/GuiHandler.scala deleted file mode 100644 index e504415be0..0000000000 --- a/src/main/scala/li/cil/oc/server/GuiHandler.scala +++ /dev/null @@ -1,9 +0,0 @@ -package li.cil.oc.server - -import li.cil.oc.common.{GuiHandler => CommonGuiHandler} -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.world.World - -object GuiHandler extends CommonGuiHandler { - override def getClientGuiElement(id: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int) = null -} diff --git a/src/main/scala/li/cil/oc/server/PacketHandler.scala b/src/main/scala/li/cil/oc/server/PacketHandler.scala index df6c97bf48..88d31e7a5d 100644 --- a/src/main/scala/li/cil/oc/server/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/server/PacketHandler.scala @@ -1,5 +1,7 @@ package li.cil.oc.server +import java.io.InputStream + import li.cil.oc.Localization import li.cil.oc.api import li.cil.oc.api.internal.Server @@ -8,29 +10,30 @@ import li.cil.oc.api.network.Connector import li.cil.oc.common.Achievement import li.cil.oc.common.PacketType import li.cil.oc.common.component.TextBuffer +import li.cil.oc.common.container import li.cil.oc.common.entity.Drone -import li.cil.oc.common.item.{Delegator, Tablet, TabletWrapper} +import li.cil.oc.common.entity.DroneInventory +import li.cil.oc.common.item.{Tablet, TabletWrapper} import li.cil.oc.common.item.data.DriveData import li.cil.oc.common.item.traits.FileSystemLike import li.cil.oc.common.tileentity._ import li.cil.oc.common.tileentity.traits.Computer import li.cil.oc.common.{PacketHandler => CommonPacketHandler} -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.network.NetHandlerPlayServer -import net.minecraft.util.EnumHand -import net.minecraftforge.common.DimensionManager -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Hand +import net.minecraft.util.RegistryKey +import net.minecraft.util.ResourceLocation +import net.minecraft.util.Util +import net.minecraft.util.registry.Registry +import net.minecraft.world.World +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fml.server.ServerLifecycleHooks object PacketHandler extends CommonPacketHandler { - @SubscribeEvent - def onPacket(e: ServerCustomPacketEvent): Unit = - onPacketData(e.getManager.getNetHandler, e.getPacket.payload, e.getHandler.asInstanceOf[NetHandlerPlayServer].player) - - override protected def world(player: EntityPlayer, dimension: Int) = - Option(DimensionManager.getWorld(dimension)) + override protected def world(player: PlayerEntity, dimension: ResourceLocation): Option[World] = + Option(ServerLifecycleHooks.getCurrentServer.getLevel(RegistryKey.create(Registry.DIMENSION_REGISTRY, dimension))) override def dispatch(p: PacketParser) { p.packetType match { @@ -41,6 +44,7 @@ object PacketHandler extends CommonPacketHandler { case PacketType.DronePower => onDronePower(p) case PacketType.KeyDown => onKeyDown(p) case PacketType.KeyUp => onKeyUp(p) + case PacketType.TextInput => onTextInput(p) case PacketType.Clipboard => onClipboard(p) case PacketType.MachineItemStateRequest => onMachineItemStateRequest(p) case PacketType.MouseClickOrDrag => onMouseClick(p) @@ -59,50 +63,55 @@ object PacketHandler extends CommonPacketHandler { } def onComputerPower(p: PacketParser): Unit = { - val entity = p.readTileEntity[Computer]() + val containerId = p.readInt() val setPower = p.readBoolean() - entity match { - case Some(t) => p.player match { - case player: EntityPlayerMP => trySetComputerPower(t.machine, setPower, player) - case _ => + p.player.containerMenu match { + case computer: container.Case if computer.containerId == containerId => { + (computer.otherInventory, p.player) match { + case (te: Computer, player: ServerPlayerEntity) => trySetComputerPower(te.machine, setPower, player) + case _ => + } } - case _ => // Invalid packet. + case robot: container.Robot if robot.containerId == containerId => { + (robot.otherInventory, p.player) match { + case (te: Computer, player: ServerPlayerEntity) => trySetComputerPower(te.machine, setPower, player) + case _ => + } + } + case _ => // Invalid packet or container closed early. } } def onServerPower(p: PacketParser): Unit = { - val entity = p.readTileEntity[Rack]() + val containerId = p.readInt() val index = p.readInt() val setPower = p.readBoolean() - entity match { - case Some(t) => { - val mountableIndex = index - t.getMountable(mountableIndex) match { - case server: Server => p.player match { - case player: EntityPlayerMP => trySetComputerPower(server.machine, setPower, player) - case _ => // Invalid packet. - } + p.player.containerMenu match { + case server: container.Server if server.containerId == containerId => { + (server.otherInventory, p.player) match { + case (comp: component.Server, player: ServerPlayerEntity) if comp.rack.getMountable(index) == comp => + trySetComputerPower(comp.machine, setPower, player) case _ => // Invalid packet. } } - case _ => // Invalid packet. + case _ => // Invalid packet or container closed early. } } def onCopyToAnalyzer(p: PacketParser) { val text = p.readUTF() val line = p.readInt() - ComponentTracker.get(p.player.world, text) match { - case Some(buffer: TextBuffer) => buffer.copyToAnalyzer(line, p.player.asInstanceOf[EntityPlayer]) + ComponentTracker.get(p.player.level, text) match { + case Some(buffer: TextBuffer) => buffer.copyToAnalyzer(line, p.player.asInstanceOf[PlayerEntity]) case _ => // Invalid Packet } } def onDriveLock(p: PacketParser): Unit = p.player match { - case player: EntityPlayerMP => { - val heldItem = player.getHeldItem(EnumHand.MAIN_HAND) - Delegator.subItem(heldItem) match { - case Some(drive: FileSystemLike) => DriveData.lock(heldItem, player) + case player: ServerPlayerEntity => { + val heldItem = player.getItemInHand(Hand.MAIN_HAND) + heldItem.getItem match { + case drive: FileSystemLike => DriveData.lock(heldItem, player) case _ => // Invalid packet } } @@ -112,10 +121,10 @@ object PacketHandler extends CommonPacketHandler { def onDriveMode(p: PacketParser): Unit = { val unmanaged = p.readBoolean() p.player match { - case player: EntityPlayerMP => - val heldItem = player.getHeldItem(EnumHand.MAIN_HAND) - Delegator.subItem(heldItem) match { - case Some(drive: FileSystemLike) => DriveData.setUnmanaged(heldItem, unmanaged) + case player: ServerPlayerEntity => + val heldItem = player.getItemInHand(Hand.MAIN_HAND) + heldItem.getItem match { + case drive: FileSystemLike => DriveData.setUnmanaged(heldItem, unmanaged) case _ => // Invalid packet. } case _ => // Invalid packet. @@ -123,28 +132,26 @@ object PacketHandler extends CommonPacketHandler { } def onDronePower(p: PacketParser): Unit = { - val entity = p.readEntity[Drone]() + val containerId = p.readInt() val power = p.readBoolean() - entity match { - case Some(drone) => p.player match { - case player: EntityPlayerMP => - if (power) { - drone.preparePowerUp() - } - trySetComputerPower(drone.machine, power, player) - case _ => + p.player.containerMenu match { + case drone: container.Drone if drone.containerId == containerId => { + (drone.otherInventory, p.player) match { + case (droneInv: DroneInventory, player: ServerPlayerEntity) => trySetComputerPower(droneInv.drone.machine, power, player) + case _ => + } } - case _ => // Invalid packet. + case _ => // Invalid packet or container closed early. } } - private def trySetComputerPower(computer: Machine, value: Boolean, player: EntityPlayerMP) { - if (computer.canInteract(player.getName)) { + private def trySetComputerPower(computer: Machine, value: Boolean, player: ServerPlayerEntity) { + if (computer.canInteract(player.getName.getString)) { if (value) { if (!computer.isPaused) { computer.start() computer.lastError match { - case message if message != null => player.sendMessage(Localization.Analyzer.LastError(message)) + case message if message != null => player.sendMessage(Localization.Analyzer.LastError(message), Util.NIL_UUID) case _ => } } @@ -157,8 +164,8 @@ object PacketHandler extends CommonPacketHandler { val address = p.readUTF() val key = p.readChar() val code = p.readInt() - ComponentTracker.get(p.player.world, address) match { - case Some(buffer: api.internal.TextBuffer) => buffer.keyDown(key, code, p.player.asInstanceOf[EntityPlayer]) + ComponentTracker.get(p.player.level, address) match { + case Some(buffer: api.internal.TextBuffer) => buffer.keyDown(key, code, p.player.asInstanceOf[PlayerEntity]) case _ => // Invalid Packet } } @@ -167,17 +174,28 @@ object PacketHandler extends CommonPacketHandler { val address = p.readUTF() val key = p.readChar() val code = p.readInt() - ComponentTracker.get(p.player.world, address) match { - case Some(buffer: api.internal.TextBuffer) => buffer.keyUp(key, code, p.player.asInstanceOf[EntityPlayer]) + ComponentTracker.get(p.player.level, address) match { + case Some(buffer: api.internal.TextBuffer) => buffer.keyUp(key, code, p.player.asInstanceOf[PlayerEntity]) case _ => // Invalid Packet } } + def onTextInput(p: PacketParser): Unit = { + val address = p.readUTF() + val codePt = p.readInt() + if (codePt >= 0 && codePt <= Character.MAX_CODE_POINT) { + ComponentTracker.get(p.player.level, address) match { + case Some(buffer: api.internal.TextBuffer) => buffer.textInput(codePt, p.player.asInstanceOf[PlayerEntity]) + case _ => // Invalid Packet + } + } + } + def onClipboard(p: PacketParser): Unit = { val address = p.readUTF() val copy = p.readUTF() - ComponentTracker.get(p.player.world, address) match { - case Some(buffer: api.internal.TextBuffer) => buffer.clipboard(copy, p.player.asInstanceOf[EntityPlayer]) + ComponentTracker.get(p.player.level, address) match { + case Some(buffer: api.internal.TextBuffer) => buffer.clipboard(copy, p.player.asInstanceOf[PlayerEntity]) case _ => // Invalid Packet } } @@ -188,9 +206,9 @@ object PacketHandler extends CommonPacketHandler { val y = p.readFloat() val dragging = p.readBoolean() val button = p.readByte() - ComponentTracker.get(p.player.world, address) match { + ComponentTracker.get(p.player.level, address) match { case Some(buffer: api.internal.TextBuffer) => - val player = p.player.asInstanceOf[EntityPlayer] + val player = p.player.asInstanceOf[PlayerEntity] if (dragging) buffer.mouseDrag(x, y, button, player) else buffer.mouseDown(x, y, button, player) case _ => // Invalid Packet @@ -202,9 +220,9 @@ object PacketHandler extends CommonPacketHandler { val x = p.readFloat() val y = p.readFloat() val button = p.readByte() - ComponentTracker.get(p.player.world, address) match { + ComponentTracker.get(p.player.level, address) match { case Some(buffer: api.internal.TextBuffer) => - val player = p.player.asInstanceOf[EntityPlayer] + val player = p.player.asInstanceOf[PlayerEntity] buffer.mouseUp(x, y, button, player) case _ => // Invalid Packet } @@ -215,9 +233,9 @@ object PacketHandler extends CommonPacketHandler { val x = p.readFloat() val y = p.readFloat() val button = p.readByte() - ComponentTracker.get(p.player.world, address) match { + ComponentTracker.get(p.player.level, address) match { case Some(buffer: api.internal.TextBuffer) => - val player = p.player.asInstanceOf[EntityPlayer] + val player = p.player.asInstanceOf[PlayerEntity] buffer.mouseScroll(x, y, button, player) case _ => // Invalid Packet } @@ -226,69 +244,78 @@ object PacketHandler extends CommonPacketHandler { def onPetVisibility(p: PacketParser) { val value = p.readBoolean() p.player match { - case player: EntityPlayerMP => + case player: ServerPlayerEntity => if (if (value) { - PetVisibility.hidden.remove(player.getName) + PetVisibility.hidden.remove(player.getName.getString) } else { - PetVisibility.hidden.add(player.getName) + PetVisibility.hidden.add(player.getName.getString) }) { // Something changed. - PacketSender.sendPetVisibility(Some(player.getName)) + PacketSender.sendPetVisibility(Some(player.getName.getString)) } case _ => // Invalid packet. } } def onRackMountableMapping(p: PacketParser): Unit = { - val entity = p.readTileEntity[Rack]() + val containerId = p.readInt() val mountableIndex = p.readInt() val nodeIndex = p.readInt() val side = p.readDirection() - entity match { - case Some(t) => p.player match { - case player: EntityPlayerMP if t.isUsableByPlayer(player) => - t.connect(mountableIndex, nodeIndex, side) - case _ => + p.player.containerMenu match { + case rack: container.Rack if rack.containerId == containerId => { + (rack.otherInventory, p.player) match { + case (t: Rack, player: ServerPlayerEntity) if t.stillValid(player) => + t.connect(mountableIndex, nodeIndex, side) + case _ => + } } - case _ => // Invalid packet. + case _ => // Invalid packet or container closed early. } } def onRackRelayState(p: PacketParser): Unit = { - val entity = p.readTileEntity[Rack]() + val containerId = p.readInt() val enabled = p.readBoolean() - entity match { - case Some(t) => p.player match { - case player: EntityPlayerMP if t.isUsableByPlayer(player) => + p.player.containerMenu match { + case rack: container.Rack if rack.containerId == containerId => { + (rack.otherInventory, p.player) match { + case (t: Rack, player: ServerPlayerEntity) if t.stillValid(player) => t.isRelayEnabled = enabled - case _ => + case _ => + } } - case _ => // Invalid packet. + case _ => // Invalid packet or container closed early. } } def onRobotAssemblerStart(p: PacketParser): Unit = { - val entity = p.readTileEntity[Assembler]() - entity match { - case Some(assembler) => - if (assembler.start(p.player match { - case player: EntityPlayerMP => player.capabilities.isCreativeMode - case _ => false - })) assembler.output.foreach(stack => Achievement.onAssemble(stack, p.player)) - case _ => // Invalid packet. + val containerId = p.readInt() + p.player.containerMenu match { + case assembler: container.Assembler if assembler.containerId == containerId => { + assembler.assembler match { + case te: Assembler => + if (te.start(p.player match { + case player: ServerPlayerEntity => player.isCreative + case _ => false + })) te.output.foreach(stack => Achievement.onAssemble(stack, p.player)) + case _ => + } + } + case _ => // Invalid packet or container closed early. } } def onRobotStateRequest(p: PacketParser): Unit = { - p.readTileEntity[RobotProxy]() match { - case Some(proxy) => proxy.world.notifyBlockUpdate(proxy.getPos, proxy.world.getBlockState(proxy.getPos), proxy.world.getBlockState(proxy.getPos), 3) + p.readBlockEntity[RobotProxy]() match { + case Some(proxy) => proxy.world.sendBlockUpdated(proxy.getBlockPos, proxy.world.getBlockState(proxy.getBlockPos), proxy.world.getBlockState(proxy.getBlockPos), 3) case _ => // Invalid packet. } } def onMachineItemStateRequest(p: PacketParser): Unit = p.player match { - case player: EntityPlayerMP => { + case player: ServerPlayerEntity => { val stack = p.readItemStack() PacketSender.sendMachineItemState(player, stack, Tablet.get(stack, p.player).machine.isRunning) } @@ -298,19 +325,19 @@ object PacketHandler extends CommonPacketHandler { def onTextBufferInit(p: PacketParser) { val address = p.readUTF() p.player match { - case entity: EntityPlayerMP => - ComponentTracker.get(p.player.world, address) match { + case entity: ServerPlayerEntity => + ComponentTracker.get(p.player.level, address) match { case Some(buffer: TextBuffer) => if (buffer.host match { case screen: Screen if !screen.isOrigin => false case _ => true }) { - val nbt = new NBTTagCompound() - buffer.data.save(nbt) - nbt.setInteger("maxWidth", buffer.getMaximumWidth) - nbt.setInteger("maxHeight", buffer.getMaximumHeight) - nbt.setInteger("viewportWidth", buffer.getViewportWidth) - nbt.setInteger("viewportHeight", buffer.getViewportHeight) + val nbt = new CompoundNBT() + buffer.data.saveData(nbt) + nbt.putInt("maxWidth", buffer.getMaximumWidth) + nbt.putInt("maxHeight", buffer.getMaximumHeight) + nbt.putInt("viewportWidth", buffer.getViewportWidth) + nbt.putInt("viewportHeight", buffer.getViewportHeight) PacketSender.sendTextBufferInit(address, nbt, entity) } case _ => // Invalid packet. @@ -320,11 +347,11 @@ object PacketHandler extends CommonPacketHandler { } def onWaypointLabel(p: PacketParser): Unit = { - val entity = p.readTileEntity[Waypoint]() + val entity = p.readBlockEntity[Waypoint]() val label = p.readUTF().take(32) entity match { case Some(waypoint) => p.player match { - case player: EntityPlayerMP if player.getDistanceSq(waypoint.x + 0.5, waypoint.y + 0.5, waypoint.z + 0.5) <= 64 => + case player: ServerPlayerEntity if player.distanceToSqr(waypoint.x + 0.5, waypoint.y + 0.5, waypoint.z + 0.5) <= 64 => if (label != waypoint.label) { waypoint.label = label PacketSender.sendWaypointLabel(waypoint) @@ -334,4 +361,6 @@ object PacketHandler extends CommonPacketHandler { case _ => // Invalid packet. } } + + protected override def createParser(stream: InputStream, player: PlayerEntity) = new PacketParser(stream, player) } diff --git a/src/main/scala/li/cil/oc/server/PacketSender.scala b/src/main/scala/li/cil/oc/server/PacketSender.scala index dc4624e7a5..a50794d6ba 100644 --- a/src/main/scala/li/cil/oc/server/PacketSender.scala +++ b/src/main/scala/li/cil/oc/server/PacketSender.scala @@ -11,19 +11,20 @@ import li.cil.oc.common.tileentity.Waypoint import li.cil.oc.common.tileentity.traits._ import li.cil.oc.util.BlockPosition import li.cil.oc.util.PackedColor -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.inventory.Container +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.inventory.container.Container import net.minecraft.item.ItemStack import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumParticleTypes +import net.minecraft.nbt.CompoundNBT +import net.minecraft.particles.IParticleData +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation import net.minecraft.util.SoundCategory import net.minecraft.util.math.BlockPos import net.minecraft.world.World import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.registries.ForgeRegistries import scala.collection.mutable @@ -37,7 +38,7 @@ object PacketSender { pb.sendToPlayersNearTileEntity(t) } - def sendAnalyze(address: String, player: EntityPlayerMP) { + def sendAnalyze(address: String, player: ServerPlayerEntity) { val pb = new SimplePacketBuilder(PacketType.Analyze) pb.writeUTF(address) @@ -55,7 +56,7 @@ object PacketSender { pb.sendToPlayersNearTileEntity(t) } - def sendClientLog(line: String, player: EntityPlayerMP) { + def sendClientLog(line: String, player: ServerPlayerEntity) { val pb = new CompressedPacketBuilder(PacketType.ClientLog) pb.writeUTF(line) @@ -63,7 +64,7 @@ object PacketSender { pb.sendToPlayer(player) } - def sendClipboard(player: EntityPlayerMP, text: String) { + def sendClipboard(player: ServerPlayerEntity, text: String) { val pb = new SimplePacketBuilder(PacketType.Clipboard) pb.writeUTF(text) @@ -90,7 +91,7 @@ object PacketSender { pb.sendToPlayersNearTileEntity(t) } - def sendMachineItemState(player: EntityPlayerMP, stack: ItemStack, isRunning: Boolean): Unit = { + def sendMachineItemState(player: ServerPlayerEntity, stack: ItemStack, isRunning: Boolean): Unit = { val pb = new SimplePacketBuilder(PacketType.MachineItemStateResponse) pb.writeItemStack(stack) @@ -109,11 +110,11 @@ object PacketSender { pb.sendToPlayersNearTileEntity(t) } - def sendContainerUpdate(c: Container, nbt: NBTTagCompound, player: EntityPlayerMP): Unit = { - if (!nbt.hasNoTags) { + def sendContainerUpdate(c: Container, nbt: CompoundNBT, player: ServerPlayerEntity): Unit = { + if (!nbt.isEmpty) { val pb = new SimplePacketBuilder(PacketType.ContainerUpdate) - pb.writeByte(c.windowId.toByte) + pb.writeInt(c.containerId) pb.writeNBT(nbt) pb.sendToPlayer(player) @@ -148,13 +149,13 @@ object PacketSender { pb.writeUTF(event.getSound) CompressedStreamTools.write(event.getData, pb) - event.getTileEntity match { + event.getBlockEntity match { case t: net.minecraft.tileentity.TileEntity => pb.writeBoolean(true) pb.writeTileEntity(t) case _ => pb.writeBoolean(false) - pb.writeInt(event.getWorld.provider.getDimension) + pb.writeUTF(event.getWorld.dimension.location.toString) pb.writeDouble(event.getX) pb.writeDouble(event.getY) pb.writeDouble(event.getZ) @@ -177,13 +178,13 @@ object PacketSender { val pb = new SimplePacketBuilder(PacketType.NetworkActivity) CompressedStreamTools.write(event.getData, pb) - event.getTileEntity match { + event.getBlockEntity match { case t: net.minecraft.tileentity.TileEntity => pb.writeBoolean(true) pb.writeTileEntity(t) case _ => pb.writeBoolean(false) - pb.writeInt(event.getWorld.provider.getDimension) + pb.writeUTF(event.getWorld.dimension.location.toString) pb.writeDouble(event.getX) pb.writeDouble(event.getY) pb.writeDouble(event.getZ) @@ -309,7 +310,7 @@ object PacketSender { pb.sendToPlayersNearTileEntity(t) } - def sendLootDisks(p: EntityPlayerMP): Unit = { + def sendLootDisks(p: ServerPlayerEntity): Unit = { // Sending as separate packets, because CompressedStreamTools hiccups otherwise... val stacks = Loot.worldDisks.map(_._1) for (stack <- stacks) { @@ -328,15 +329,15 @@ object PacketSender { } } - def sendNanomachineConfiguration(player: EntityPlayer): Unit = { + def sendNanomachineConfiguration(player: PlayerEntity): Unit = { val pb = new SimplePacketBuilder(PacketType.NanomachinesConfiguration) pb.writeEntity(player) api.Nanomachines.getController(player) match { case controller: ControllerImpl => pb.writeBoolean(true) - val nbt = new NBTTagCompound() - controller.save(nbt) + val nbt = new CompoundNBT() + controller.saveData(nbt) pb.writeNBT(nbt) case _ => pb.writeBoolean(false) @@ -345,7 +346,7 @@ object PacketSender { pb.sendToPlayersNearEntity(player) } - def sendNanomachineInputs(player: EntityPlayer): Unit = { + def sendNanomachineInputs(player: PlayerEntity): Unit = { api.Nanomachines.getController(player) match { case controller: ControllerImpl => val pb = new SimplePacketBuilder(PacketType.NanomachinesInputs) @@ -360,7 +361,7 @@ object PacketSender { } } - def sendNanomachinePower(player: EntityPlayer): Unit = { + def sendNanomachinePower(player: PlayerEntity): Unit = { api.Nanomachines.getController(player) match { case controller: ControllerImpl => val pb = new SimplePacketBuilder(PacketType.NanomachinesPower) @@ -383,22 +384,22 @@ object PacketSender { pb.sendToPlayersNearTileEntity(t) } - def sendParticleEffect(position: BlockPosition, particleType: EnumParticleTypes, count: Int, velocity: Double, direction: Option[EnumFacing] = None): Unit = if (count > 0) { + def sendParticleEffect(position: BlockPosition, particleType: IParticleData, count: Int, velocity: Double, direction: Option[Direction] = None): Unit = if (count > 0) { val pb = new SimplePacketBuilder(PacketType.ParticleEffect) - pb.writeInt(position.world.get.provider.getDimension) + pb.writeUTF(position.world.get.dimension.location.toString) pb.writeInt(position.x) pb.writeInt(position.y) pb.writeInt(position.z) pb.writeDouble(velocity) pb.writeDirection(direction) - pb.writeInt(particleType.getParticleID) + pb.writeRegistryEntry(ForgeRegistries.PARTICLE_TYPES, particleType.getType()) pb.writeByte(count.toByte) pb.sendToNearbyPlayers(position.world.get, position.x, position.y, position.z, Some(32.0)) } - def sendPetVisibility(name: Option[String] = None, player: Option[EntityPlayerMP] = None) { + def sendPetVisibility(name: Option[String] = None, player: Option[ServerPlayerEntity] = None) { val pb = new SimplePacketBuilder(PacketType.PetVisibility) name match { @@ -443,10 +444,10 @@ object PacketSender { val pb = new SimplePacketBuilder(PacketType.RackInventory) pb.writeTileEntity(t) - pb.writeInt(t.getSizeInventory) - for (slot <- 0 until t.getSizeInventory) { + pb.writeInt(t.getContainerSize) + for (slot <- 0 until t.getContainerSize) { pb.writeInt(slot) - pb.writeItemStack(t.getStackInSlot(slot)) + pb.writeItemStack(t.getItem(slot)) } pb.sendToPlayersNearTileEntity(t) @@ -458,7 +459,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeInt(1) pb.writeInt(slot) - pb.writeItemStack(t.getStackInSlot(slot)) + pb.writeItemStack(t.getItem(slot)) pb.sendToPlayersNearTileEntity(t) } @@ -477,8 +478,8 @@ object PacketSender { val pb = new SimplePacketBuilder(PacketType.RaidStateChange) pb.writeTileEntity(t) - for (slot <- 0 until t.getSizeInventory) { - pb.writeBoolean(!t.getStackInSlot(slot).isEmpty) + for (slot <- 0 until t.getContainerSize) { + pb.writeBoolean(!t.getItem(slot).isEmpty) } pb.sendToPlayersNearTileEntity(t) @@ -489,7 +490,7 @@ object PacketSender { pb.writeTileEntity(t) pb.writeBoolean(t.isOutputEnabled) - for (d <- EnumFacing.values) { + for (d <- Direction.values) { pb.writeByte(t.getOutput(d)) } @@ -505,11 +506,11 @@ object PacketSender { pb.sendToPlayersNearHost(t) } - def sendRobotMove(t: tileentity.Robot, position: BlockPos, direction: EnumFacing) { + def sendRobotMove(t: tileentity.Robot, position: BlockPos, direction: Direction) { val pb = new SimplePacketBuilder(PacketType.RobotMove) // Custom pb.writeTileEntity() with fake coordinates (valid for the client). - pb.writeInt(t.world.provider.getDimension) + pb.writeUTF(t.world.dimension.location.toString) pb.writeInt(position.getX) pb.writeInt(position.getY) pb.writeInt(position.getZ) @@ -683,7 +684,7 @@ object PacketSender { pb.writeInt(fromRow) } - def appendTextBufferRamInit(pb: PacketBuilder, address: String, id: Int, nbt: NBTTagCompound): Unit = { + def appendTextBufferRamInit(pb: PacketBuilder, address: String, id: Int, nbt: CompoundNBT): Unit = { pb.writePacketType(PacketType.TextBufferRamInit) pb.writeUTF(address) @@ -742,7 +743,7 @@ object PacketSender { } } - def sendTextBufferInit(address: String, value: NBTTagCompound, player: EntityPlayerMP) { + def sendTextBufferInit(address: String, value: CompoundNBT, player: ServerPlayerEntity) { val pb = new CompressedPacketBuilder(PacketType.TextBufferInit) pb.writeUTF(address) @@ -772,7 +773,7 @@ object PacketSender { def sendSound(world: World, x: Double, y: Double, z: Double, sound: ResourceLocation, category: SoundCategory, range: Double) { val pb = new SimplePacketBuilder(PacketType.SoundEffect) - pb.writeInt(world.provider.getDimension) + pb.writeUTF(world.dimension.location.toString) pb.writeDouble(x) pb.writeDouble(y) pb.writeDouble(z) @@ -787,7 +788,7 @@ object PacketSender { val pb = new SimplePacketBuilder(PacketType.Sound) val blockPos = BlockPosition(x, y, z) - pb.writeInt(world.provider.getDimension) + pb.writeUTF(world.dimension.location.toString) pb.writeInt(blockPos.x) pb.writeInt(blockPos.y) pb.writeInt(blockPos.z) @@ -801,7 +802,7 @@ object PacketSender { val pb = new SimplePacketBuilder(PacketType.SoundPattern) val blockPos = BlockPosition(x, y, z) - pb.writeInt(world.provider.getDimension) + pb.writeUTF(world.dimension.location.toString) pb.writeInt(blockPos.x) pb.writeInt(blockPos.y) pb.writeInt(blockPos.z) diff --git a/src/main/scala/li/cil/oc/server/Proxy.scala b/src/main/scala/li/cil/oc/server/Proxy.scala deleted file mode 100644 index 692112cdd2..0000000000 --- a/src/main/scala/li/cil/oc/server/Proxy.scala +++ /dev/null @@ -1,14 +0,0 @@ -package li.cil.oc.server - -import li.cil.oc.OpenComputers -import li.cil.oc.common.{Proxy => CommonProxy} -import net.minecraftforge.fml.common.event.FMLInitializationEvent -import net.minecraftforge.fml.common.network.NetworkRegistry - -private[oc] class Proxy extends CommonProxy { - override def init(e: FMLInitializationEvent) { - super.init(e) - - NetworkRegistry.INSTANCE.registerGuiHandler(OpenComputers, GuiHandler) - } -} diff --git a/src/main/scala/li/cil/oc/server/agent/AgentContainer.scala b/src/main/scala/li/cil/oc/server/agent/AgentContainer.scala deleted file mode 100644 index 25d262f745..0000000000 --- a/src/main/scala/li/cil/oc/server/agent/AgentContainer.scala +++ /dev/null @@ -1,43 +0,0 @@ -package li.cil.oc.server.agent - -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.inventory.{Container, IContainerListener, IInventory, Slot} -import li.cil.oc.server.agent -import net.minecraft.item.ItemStack -import net.minecraft.util.NonNullList - -class AgentContainer(player: agent.Player) extends Container { - { - for (slot <- 0 until player.agent.equipmentInventory.getSizeInventory) { - this.addSlotToContainer(new Slot(player.inventory, -1 - slot, 0, 0)) - } - for (slot <- 0 until player.agent.mainInventory.getSizeInventory) { - this.addSlotToContainer(new Slot(player.inventory, slot, 0, 0)) - } - - this.addListener(new IContainerListener { - override def sendAllContents(containerToSend: Container, itemsList: NonNullList[ItemStack]): Unit = {} - - override def sendWindowProperty(containerIn: Container, varToUpdate: Int, newValue: Int): Unit = {} - - override def sendAllWindowProperties(containerIn: Container, inventory: IInventory): Unit = {} - - override def sendSlotContents(containerToSend: Container, index: Int, stack: ItemStack): Unit = { - // an action has updated the agent.inventory via slots - // thus the player.inventory is outdated in this regard - val relativeIndex: Int = containerToSend.inventorySlots.get(index).getSlotIndex - - if (relativeIndex < 0) { - if (~relativeIndex < player.inventory.armorInventory.size) { - player.inventory.armorInventory.set(~relativeIndex, stack) - } - } - else if (relativeIndex < player.inventory.mainInventory.size) { - player.inventory.mainInventory.set(relativeIndex, stack) - } - } - }) - } - - override def canInteractWith(player: EntityPlayer): Boolean = true -} diff --git a/src/main/scala/li/cil/oc/server/agent/FakeNetworkManager.scala b/src/main/scala/li/cil/oc/server/agent/FakeNetworkManager.scala index 310ed05e90..9ef8e9c1fd 100644 --- a/src/main/scala/li/cil/oc/server/agent/FakeNetworkManager.scala +++ b/src/main/scala/li/cil/oc/server/agent/FakeNetworkManager.scala @@ -2,12 +2,12 @@ package li.cil.oc.server.agent import io.netty.util.concurrent.Future import io.netty.util.concurrent.GenericFutureListener -import net.minecraft.network.EnumPacketDirection import net.minecraft.network.NetworkManager -import net.minecraft.network.Packet +import net.minecraft.network.IPacket +import net.minecraft.network.PacketDirection -object FakeNetworkManager extends NetworkManager(EnumPacketDirection.CLIENTBOUND) { - override def sendPacket(packetIn: Packet[_]): Unit = {} +object FakeNetworkManager extends NetworkManager(PacketDirection.CLIENTBOUND) { + override def send(packetIn: IPacket[_]): Unit = {} - override def sendPacket(packetIn: Packet[_], listener: GenericFutureListener[_ <: Future[_ >: Void]], listeners: GenericFutureListener[_ <: Future[_ >: Void]]*): Unit = {} + override def send(packetIn: IPacket[_], listener: GenericFutureListener[_ <: Future[_ >: Void]]): Unit = {} } diff --git a/src/main/scala/li/cil/oc/server/agent/Inventory.scala b/src/main/scala/li/cil/oc/server/agent/Inventory.scala index 6846193336..7d5d850e6c 100644 --- a/src/main/scala/li/cil/oc/server/agent/Inventory.scala +++ b/src/main/scala/li/cil/oc/server/agent/Inventory.scala @@ -1,41 +1,46 @@ package li.cil.oc.server.agent +import java.util.function.Predicate + import li.cil.oc.api.internal import li.cil.oc.util.ExtendedInventory._ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.InventoryPlayer -import net.minecraft.item.Item +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagList -import net.minecraft.block.state.IBlockState +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.ListNBT +import net.minecraft.util.DamageSource +import net.minecraft.util.text.ITextComponent +import net.minecraft.util.text.StringTextComponent +import net.minecraft.block.BlockState import scala.collection.immutable -class Inventory(playerEntity: EntityPlayer, val agent: internal.Agent) extends InventoryPlayer(playerEntity) { +class Inventory(playerEntity: PlayerEntity, val agent: internal.Agent) extends PlayerInventory(playerEntity) { - private def selectedItemStack: ItemStack = agent.mainInventory.getStackInSlot(agent.selectedSlot) + private def selectedItemStack: ItemStack = agent.mainInventory.getItem(agent.selectedSlot) - private def inventorySlots: immutable.IndexedSeq[Int] = (agent.selectedSlot until getSizeInventory) ++ (0 until agent.selectedSlot) + private def inventorySlots: immutable.IndexedSeq[Int] = (agent.selectedSlot until getContainerSize) ++ (0 until agent.selectedSlot) - override def getCurrentItem: ItemStack = agent.equipmentInventory.getStackInSlot(0) + override def getSelected: ItemStack = agent.equipmentInventory.getItem(0) - override def getFirstEmptyStack: Int = { + override def getFreeSlot: Int = { if (selectedItemStack.isEmpty) agent.selectedSlot - else inventorySlots.find(getStackInSlot(_).isEmpty).getOrElse(-1) + else inventorySlots.find(getItem(_).isEmpty).getOrElse(-1) } - override def changeCurrentItem(direction: Int) {} + override def pickSlot(direction: Int) {} - override def clearMatchingItems(item: Item, damage: Int, count: Int, tag: NBTTagCompound): Int = 0 + override def clearOrCountMatchingItems(f: Predicate[ItemStack], count: Int, inv: IInventory): Int = 0 - override def decrementAnimations() { - for (slot <- 0 until getSizeInventory) { - StackOption(getStackInSlot(slot)) match { - case SomeStack(stack) => try stack.updateAnimation(agent.world, if (!agent.world.isRemote) agent.player else null, slot, slot == 0) catch { + override def tick() { + for (slot <- 0 until getContainerSize) { + StackOption(getItem(slot)) match { + case SomeStack(stack) => try stack.inventoryTick(agent.world, if (!agent.world.isClientSide) agent.player else null, slot, slot == 0) catch { case ignored: NullPointerException => // Client side item updates that need a player instance... } case _ => @@ -43,61 +48,59 @@ class Inventory(playerEntity: EntityPlayer, val agent: internal.Agent) extends I } } - override def addItemStackToInventory(stack: ItemStack): Boolean = { + override def add(stack: ItemStack): Boolean = { val slots = this.indices.drop(agent.selectedSlot) ++ this.indices.take(agent.selectedSlot) InventoryUtils.insertIntoInventory(stack, InventoryUtils.asItemHandler(this), slots = Option(slots)) } - override def canHarvestBlock(state: IBlockState): Boolean = state.getMaterial.isToolNotRequired || (!getCurrentItem.isEmpty && getCurrentItem.canHarvestBlock(state)) - - override def getDestroySpeed(state: IBlockState): Float = if (getCurrentItem.isEmpty) 1f else getCurrentItem.getDestroySpeed(state) + override def getDestroySpeed(state: BlockState): Float = if (getSelected.isEmpty) 1f else getSelected.getDestroySpeed(state) - override def writeToNBT(nbt: NBTTagList): NBTTagList = nbt + override def save(nbt: ListNBT): ListNBT = nbt - override def readFromNBT(nbt: NBTTagList) {} + override def load(nbt: ListNBT) {} - override def armorItemInSlot(slot: Int): ItemStack = ItemStack.EMPTY + override def getArmor(slot: Int): ItemStack = ItemStack.EMPTY - override def damageArmor(damage: Float) {} + override def hurtArmor(source: DamageSource, damage: Float) {} - override def dropAllItems(): Unit = {} + override def dropAll(): Unit = {} - override def hasItemStack(stack: ItemStack): Boolean = (0 until getSizeInventory).map(getStackInSlot).filter(!_.isEmpty).exists(_.isItemEqual(stack)) + override def contains(stack: ItemStack): Boolean = (0 until getContainerSize).map(getItem).filter(!_.isEmpty).exists(_.sameItem(stack)) - override def copyInventory(from: InventoryPlayer) {} + override def replaceWith(from: PlayerInventory) {} // IInventory - override def getSizeInventory: Int = agent.mainInventory.getSizeInventory + override def getContainerSize: Int = agent.mainInventory.getContainerSize - override def getStackInSlot(slot: Int): ItemStack = - if (slot < 0) agent.equipmentInventory.getStackInSlot(~slot) - else agent.mainInventory.getStackInSlot(slot) + override def getItem(slot: Int): ItemStack = + if (slot < 0) agent.equipmentInventory.getItem(~slot) + else agent.mainInventory.getItem(slot) - override def decrStackSize(slot: Int, amount: Int): ItemStack = { - if (slot < 0) agent.equipmentInventory.decrStackSize(~slot, amount) - else agent.mainInventory.decrStackSize(slot, amount) + override def removeItem(slot: Int, amount: Int): ItemStack = { + if (slot < 0) agent.equipmentInventory.removeItem(~slot, amount) + else agent.mainInventory.removeItem(slot, amount) } - override def removeStackFromSlot(slot: Int): ItemStack = { - if (slot < 0) agent.equipmentInventory.removeStackFromSlot(~slot) - else agent.mainInventory.removeStackFromSlot(slot) + override def removeItemNoUpdate(slot: Int): ItemStack = { + if (slot < 0) agent.equipmentInventory.removeItemNoUpdate(~slot) + else agent.mainInventory.removeItemNoUpdate(slot) } - override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = { - if (slot < 0) agent.equipmentInventory.setInventorySlotContents(~slot, stack) - else agent.mainInventory.setInventorySlotContents(slot, stack) + override def setItem(slot: Int, stack: ItemStack): Unit = { + if (slot < 0) agent.equipmentInventory.setItem(~slot, stack) + else agent.mainInventory.setItem(slot, stack) } - override def getName: String = agent.mainInventory.getName + override def getName: ITextComponent = new StringTextComponent(agent.name) - override def getInventoryStackLimit: Int = agent.mainInventory.getInventoryStackLimit + override def getMaxStackSize: Int = agent.mainInventory.getMaxStackSize - override def markDirty(): Unit = agent.mainInventory.markDirty() + override def setChanged(): Unit = agent.mainInventory.setChanged() - override def isUsableByPlayer(player: EntityPlayer): Boolean = agent.mainInventory.isUsableByPlayer(player) + override def stillValid(player: PlayerEntity): Boolean = agent.mainInventory.stillValid(player) - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = - if (slot < 0) agent.equipmentInventory.isItemValidForSlot(~slot, stack) - else agent.mainInventory.isItemValidForSlot(slot, stack) + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = + if (slot < 0) agent.equipmentInventory.canPlaceItem(~slot, stack) + else agent.mainInventory.canPlaceItem(slot, stack) } diff --git a/src/main/scala/li/cil/oc/server/agent/Player.scala b/src/main/scala/li/cil/oc/server/agent/Player.scala index f56497d32d..584919f530 100644 --- a/src/main/scala/li/cil/oc/server/agent/Player.scala +++ b/src/main/scala/li/cil/oc/server/agent/Player.scala @@ -3,6 +3,7 @@ package li.cil.oc.server.agent import java.util import java.util.UUID +import com.mojang.datafixers.util.Either import com.mojang.authlib.GameProfile import li.cil.oc.OpenComputers import li.cil.oc.Settings @@ -10,49 +11,68 @@ import li.cil.oc.api.event._ import li.cil.oc.api.internal import li.cil.oc.api.network.Connector import li.cil.oc.common.EventHandler +import li.cil.oc.server.agent.{Inventory => AgentInventory} import li.cil.oc.util.BlockPosition import li.cil.oc.util.InventoryUtils -import net.minecraft.block.BlockPistonBase +import net.minecraft.block.PistonBlock import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.IMerchant -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.entity.player.EntityPlayer.SleepResult -import net.minecraft.init.Blocks -import net.minecraft.init.Items +import net.minecraft.entity.EntitySize +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.Pose +import net.minecraft.entity.item.ItemEntity +import net.minecraft.entity.merchant.IMerchant +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerEntity.SleepResult +import net.minecraft.block.Blocks +import net.minecraft.item.Items import net.minecraft.inventory._ -import net.minecraft.item.ItemBlock +import net.minecraft.inventory.container.INamedContainerProvider +import net.minecraft.inventory.container.PlayerContainer +import net.minecraft.item.BlockItem +import net.minecraft.item.ItemUseContext import net.minecraft.item.ItemStack -import net.minecraft.network.NetHandlerPlayServer -import net.minecraft.potion.PotionEffect -import net.minecraft.server.management.{PlayerInteractionManager, UserListOpsEntry} +import net.minecraft.item.MerchantOffers +import net.minecraft.network.play.ServerPlayNetHandler +import net.minecraft.network.play.client.CPlayerDiggingPacket +import net.minecraft.potion.EffectInstance +import net.minecraft.server.management.{PlayerInteractionManager, OpEntry} import net.minecraft.tileentity._ -import net.minecraft.util.EnumFacing -import net.minecraft.util._ +import net.minecraft.util.ActionResultType +import net.minecraft.util.DamageSource +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Vec3d +import net.minecraft.util.math.BlockRayTraceResult +import net.minecraft.util.math.vector.Vector3d import net.minecraft.util.text.ITextComponent -import net.minecraft.util.text.TextComponentString -import net.minecraft.world.IInteractionObject +import net.minecraft.util.text.StringTextComponent import net.minecraft.world.World -import net.minecraft.world.WorldServer +import net.minecraft.world.server.ServerWorld import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayer +import net.minecraftforge.common.util.LazyOptional +import net.minecraftforge.common.util.NonNullSupplier import net.minecraftforge.event.ForgeEventFactory import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent import net.minecraftforge.event.entity.player.PlayerInteractEvent import net.minecraftforge.fml.common.ObfuscationReflectionHelper -import net.minecraftforge.fml.common.eventhandler.{Event, EventPriority, SubscribeEvent} +import net.minecraftforge.eventbus.api.{Event, EventPriority, SubscribeEvent} import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.wrapper._ -import scala.collection.convert.WrapAsScala._ +import scala.jdk.CollectionConverters._ object Player { + // These use unobfuscated names because they're added by forge (LazyOptional / capabilities). + private val playerMainHandler = ObfuscationReflectionHelper.findField(classOf[PlayerEntity], "playerMainHandler") + + private val playerEquipmentHandler = ObfuscationReflectionHelper.findField(classOf[PlayerEntity], "playerEquipmentHandler") + + private val playerJoinedHandler = ObfuscationReflectionHelper.findField(classOf[PlayerEntity], "playerJoinedHandler") + def profileFor(agent: internal.Agent): GameProfile = { val uuid = agent.ownerUUID - val randomId = (agent.world.rand.nextInt(0xFFFFFF) + 1).toString + val randomId = (agent.world.random.nextInt(0xFFFFFF) + 1).toString val name = Settings.get.nameFormat. replace("$player$", agent.ownerName). replace("$random$", randomId) @@ -71,149 +91,152 @@ object Player { } } - def updatePositionAndRotation(player: Player, facing: EnumFacing, side: EnumFacing) { + def updatePositionAndRotation(player: Player, facing: Direction, side: Direction) { player.facing = facing player.side = side - val direction = new Vec3d( - facing.getFrontOffsetX + side.getFrontOffsetX, - facing.getFrontOffsetY + side.getFrontOffsetY, - facing.getFrontOffsetZ + side.getFrontOffsetZ).normalize() + val direction = new Vector3d( + facing.getStepX + side.getStepX, + facing.getStepY + side.getStepY, + facing.getStepZ + side.getStepZ).normalize() val yaw = Math.toDegrees(-Math.atan2(direction.x, direction.z)).toFloat val pitch = Math.toDegrees(-Math.atan2(direction.y, Math.sqrt((direction.x * direction.x) + (direction.z * direction.z)))).toFloat * 0.99f - player.setLocationAndAngles(player.agent.xPosition, player.agent.yPosition, player.agent.zPosition, yaw, pitch) - player.prevRotationPitch = player.rotationPitch - player.prevRotationYaw = player.rotationYaw + player.setPos(player.agent.xPosition, player.agent.yPosition, player.agent.zPosition) + player.xRot = pitch % 360f + player.yRot = yaw % 360f + player.xRotO = player.xRot + player.yRotO = player.yRot } - def setInventoryPlayerItems(player: Player): Unit = { + def setPlayerInventoryItems(player: Player): Unit = { // the offhand is simply the agent's tool item val agent = player.agent def setCopyOrNull(inv: net.minecraft.util.NonNullList[ItemStack], agentInv: IInventory, slot: Int): Unit = { - val item = agentInv.getStackInSlot(slot) - inv(slot) = if (item != null) item.copy() else ItemStack.EMPTY + val item = agentInv.getItem(slot) + inv.set(slot, if (item != null) item.copy() else ItemStack.EMPTY) } for (i <- 0 until 4) { - setCopyOrNull(player.inventory.armorInventory, agent.equipmentInventory, i) + setCopyOrNull(player.inventory.armor, agent.equipmentInventory, i) } - // mainInventory is 36 items + // items is 36 items // the agent inventory is 100 items with some space for components // leaving us 88..we'll copy what we can - val size = player.inventory.mainInventory.length min agent.mainInventory.getSizeInventory + val size = player.inventory.items.size min agent.mainInventory.getContainerSize for (i <- 0 until size) { - setCopyOrNull(player.inventory.mainInventory, agent.mainInventory, i) + setCopyOrNull(player.inventory.items, agent.mainInventory, i) } - player.inventoryContainer.detectAndSendChanges() + player.inventoryMenu.broadcastChanges() } - def detectInventoryPlayerChanges(player: Player): Unit = { + def detectPlayerInventoryChanges(player: Player): Unit = { val agent = player.agent - player.inventoryContainer.detectAndSendChanges() + player.inventoryMenu.broadcastChanges() // The follow code will set agent.inventories = FakePlayer's inv.stack def setCopy(inv: IInventory, index: Int, item: ItemStack): Unit = { val result = if (item != null) item.copy else ItemStack.EMPTY - val current = inv.getStackInSlot(index) - if (!ItemStack.areItemStacksEqual(result, current)) { - inv.setInventorySlotContents(index, result) + val current = inv.getItem(index) + if (!ItemStack.matches(result, current)) { + inv.setItem(index, result) } } for (i <- 0 until 4) { - setCopy(agent.equipmentInventory(), i, player.inventory.armorInventory(i)) + setCopy(agent.equipmentInventory(), i, player.inventory.armor.get(i)) } - val size = player.inventory.mainInventory.length min agent.mainInventory.getSizeInventory + val size = player.inventory.items.size min agent.mainInventory.getContainerSize for (i <- 0 until size) { - setCopy(agent.mainInventory, i, player.inventory.mainInventory(i)) + setCopy(agent.mainInventory, i, player.inventory.items.get(i)) } } } -class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanceOf[WorldServer], Player.profileFor(agent)) { - connection= new NetHandlerPlayServer(mcServer, FakeNetworkManager, this) +class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanceOf[ServerWorld], Player.profileFor(agent)) { + connection= new ServerPlayNetHandler(server, FakeNetworkManager, this) - capabilities.allowFlying = true - capabilities.disableDamage = true - capabilities.isFlying = true - onGround = true + abilities.mayfly = true + abilities.invulnerable = true + abilities.flying = true + setOnGround(true) - override def getYOffset = 0.5f + override def getMyRidingOffset = 0.5 - override def getEyeHeight = 0f + override def getStandingEyeHeight(pose: Pose, size: EntitySize) = 0f - setSize(1, 1) + override def getDimensions(pose: Pose) = new EntitySize(1, 1, true) + refreshDimensions() { - this.inventory = new Inventory(this, agent) - this.inventory.player = this + this.inventory = new AgentInventory(this, agent) // because the inventory was just overwritten, the container is now detached - this.inventoryContainer = new AgentContainer(this) - this.openContainer = this.inventoryContainer + this.inventoryMenu = new PlayerContainer(inventory, !level.isClientSide, this) + this.containerMenu = this.inventoryMenu try { - ObfuscationReflectionHelper.setPrivateValue(classOf[EntityPlayer], this, new PlayerMainInvWrapper(inventory), "playerMainHandler") - ObfuscationReflectionHelper.setPrivateValue(classOf[EntityPlayer], this, new CombinedInvWrapper(new PlayerArmorInvWrapper(inventory), new PlayerOffhandInvWrapper(inventory)), "playerEquipmentHandler") - ObfuscationReflectionHelper.setPrivateValue(classOf[EntityPlayer], this, new PlayerInvWrapper(inventory), "playerJoinedHandler") + Player.playerMainHandler.set(this, LazyOptional.of(new NonNullSupplier[IItemHandler] { + override def get = new PlayerMainInvWrapper(inventory) + })) + Player.playerEquipmentHandler.set(this, LazyOptional.of(new NonNullSupplier[IItemHandler] { + override def get = new CombinedInvWrapper(new PlayerArmorInvWrapper(inventory), new PlayerOffhandInvWrapper(inventory)) + })) + Player.playerJoinedHandler.set(this, LazyOptional.of(new NonNullSupplier[IItemHandler] { + override def get = new PlayerInvWrapper(inventory) + })) } catch { case _: Exception => } } - var facing, side = EnumFacing.SOUTH + var facing, side = Direction.SOUTH - override def getPosition = new BlockPos(posX, posY, posZ) - - override def getDefaultEyeHeight = 0f - - override def getDisplayName = new TextComponentString(agent.name) - - interactionManager.setBlockReachDistance(1) + override def getName = new StringTextComponent(agent.name) // ----------------------------------------------------------------------- // - def closestEntity[Type <: Entity](clazz: Class[Type], side: EnumFacing = facing): Option[Entity] = { + def closestEntity[Type <: Entity](clazz: Class[Type], side: Direction = facing): Option[Entity] = { val bounds = BlockPosition(agent).offset(side).bounds - Option(world.findNearestEntityWithinAABB(clazz, bounds, this)) + val candidates = level.getEntitiesOfClass(clazz, bounds, null) + if (candidates.isEmpty) return None + Some(candidates.asScala.minBy(e => distanceToSqr(e))) } - def entitiesOnSide[Type <: Entity](clazz: Class[Type], side: EnumFacing): util.List[Type] = { + def entitiesOnSide[Type <: Entity](clazz: Class[Type], side: Direction): util.List[Type] = { entitiesInBlock(clazz, BlockPosition(agent).offset(side)) } def entitiesInBlock[Type <: Entity](clazz: Class[Type], blockPos: BlockPosition): util.List[Type] = { - world.getEntitiesWithinAABB(clazz, blockPos.bounds) + level.getEntitiesOfClass(clazz, blockPos.bounds, null) } - private def adjacentItems: util.List[EntityItem] = { - world.getEntitiesWithinAABB(classOf[EntityItem], BlockPosition(agent).bounds.grow(2, 2, 2)) + private def adjacentItems: util.List[ItemEntity] = { + level.getEntitiesOfClass(classOf[ItemEntity], BlockPosition(agent).bounds.inflate(2, 2, 2), null) } - private def collectDroppedItems(itemsBefore: Iterable[EntityItem]) { - val itemsAfter = adjacentItems - val itemsDropped = itemsAfter -- itemsBefore + private def collectDroppedItems(itemsBefore: Iterable[ItemEntity]) { + val itemsDropped = adjacentItems.asScala --= itemsBefore if (itemsDropped.nonEmpty) { for (drop <- itemsDropped) { - drop.setNoPickupDelay() - drop.onCollideWithPlayer(this) + drop.setDefaultPickUpDelay() + drop.playerTouch(this) } } } // ----------------------------------------------------------------------- // - override def attackTargetEntityWithCurrentItem(entity: Entity) { + override def attack(entity: Entity) { callUsingItemInSlot(agent.equipmentInventory, 0, stack => entity match { - case player: EntityPlayer if !canAttackPlayer(player) => // Avoid player damage. + case player: PlayerEntity if !canHarmPlayer(player) => // Avoid player damage. case _ => val event = new RobotAttackEntityEvent.Pre(agent, entity) MinecraftForge.EVENT_BUS.post(event) if (!event.isCanceled) { - super.attackTargetEntityWithCurrentItem(entity) + super.attack(entity) MinecraftForge.EVENT_BUS.post(new RobotAttackEntityEvent.Post(agent, entity)) } }) } - override def interactOn(entity: Entity, hand: EnumHand): EnumActionResult = { + override def interactOn(entity: Entity, hand: Hand): ActionResultType = { val cancel = try MinecraftForge.EVENT_BUS.post(new PlayerInteractEvent.EntityInteract(this, hand, entity)) catch { case t: Throwable => if (!t.getStackTrace.exists(_.getClassName.startsWith("mods.battlegear2."))) { @@ -222,42 +245,43 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc false } if(!cancel && callUsingItemInSlot(agent.equipmentInventory, 0, stack => { - val result = isItemUseAllowed(stack) && (entity.processInitialInteract(this, hand) || (entity match { - case living: EntityLivingBase if !getHeldItemMainhand.isEmpty => getHeldItemMainhand.interactWithEntity(this, living, hand) + val result = isItemUseAllowed(stack) && (entity.interact(this, hand).consumesAction || (entity match { + case living: LivingEntity if !getItemInHand(Hand.MAIN_HAND).isEmpty => getItemInHand(Hand.MAIN_HAND).interactLivingEntity(this, living, hand).consumesAction case _ => false })) - if (!getHeldItemMainhand.isEmpty) { - if (getHeldItemMainhand.getCount <= 0) { - val orig = getHeldItemMainhand - this.inventory.setInventorySlotContents(this.inventory.currentItem, ItemStack.EMPTY) + if (!getItemInHand(Hand.MAIN_HAND).isEmpty) { + if (getItemInHand(Hand.MAIN_HAND).getCount <= 0) { + val orig = getItemInHand(Hand.MAIN_HAND) + this.inventory.setItem(this.inventory.selected, ItemStack.EMPTY) ForgeEventFactory.onPlayerDestroyItem(this, orig, hand) } else { // because of various hacks for IC2, we expect the in-hand result to be moved to our offhand buffer - this.inventory.offHandInventory.set(0, getHeldItemMainhand) - this.inventory.setInventorySlotContents(this.inventory.currentItem, ItemStack.EMPTY) + this.inventory.offhand.set(0, getItemInHand(Hand.MAIN_HAND)) + this.inventory.setItem(this.inventory.selected, ItemStack.EMPTY) } } result - })) EnumActionResult.SUCCESS else EnumActionResult.PASS + })) ActionResultType.sidedSuccess(level.isClientSide) else ActionResultType.PASS } - def activateBlockOrUseItem(pos: BlockPos, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float, duration: Double): ActivationType.Value = { + def activateBlockOrUseItem(pos: BlockPos, side: Direction, hitX: Float, hitY: Float, hitZ: Float, duration: Double): ActivationType.Value = { callUsingItemInSlot(agent.equipmentInventory, 0, stack => { if (shouldCancel(() => fireRightClickBlock(pos, side))) { return ActivationType.None } val item = if (!stack.isEmpty) stack.getItem else null - if (item != null && item.onItemUseFirst(this, world, pos, side, hitX, hitY, hitZ, EnumHand.OFF_HAND) == EnumActionResult.SUCCESS) { + val state = level.getBlockState(pos) + val traceEndPos = new Vector3d(pos.getX + hitX, pos.getY + hitY, pos.getZ + hitZ) + val traceCtx = if (state.getBlock.isAir(state, level, pos)) BlockRayTraceResult.miss(traceEndPos, side, pos) else new BlockRayTraceResult(traceEndPos, side, pos, false) + if (item != null && item.onItemUseFirst(stack, new ItemUseContext(level, this, Hand.OFF_HAND, stack, traceCtx)).consumesAction) { return ActivationType.ItemUsed } - val state = world.getBlockState(pos) - val block = state.getBlock - val canActivate = block != Blocks.AIR && Settings.get.allowActivateBlocks - val shouldActivate = canActivate && (!isSneaking || (item == null || item.doesSneakBypassUse(stack, world, pos, this))) + val canActivate = !state.getBlock.isAir(state, level, pos) && Settings.get.allowActivateBlocks + val shouldActivate = canActivate && (!isCrouching || (item == null || item.doesSneakBypassUse(stack, level, pos, this))) val result = - if (shouldActivate && block.onBlockActivated(world, pos, state, this, EnumHand.OFF_HAND, side, hitX, hitY, hitZ)) + if (shouldActivate && state.use(level, this, Hand.OFF_HAND, new BlockRayTraceResult(new Vector3d(hitX, hitY, hitZ), side, pos, false)).consumesAction) ActivationType.BlockActivated else if (duration <= Double.MinPositiveValue && isItemUseAllowed(stack) && tryPlaceBlockWhileHandlingFunnySpecialCases(stack, pos, side, hitX, hitY, hitZ)) ActivationType.ItemPlaced @@ -270,53 +294,52 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc }) } - override def setItemStackToSlot(slotIn: EntityEquipmentSlot, stack: ItemStack): Unit = { - var superCall: () => Unit = () => super.setItemStackToSlot(slotIn, stack) - if (slotIn == EntityEquipmentSlot.MAINHAND) { - agent.equipmentInventory.setInventorySlotContents(0, stack) + override def setItemSlot(slotIn: EquipmentSlotType, stack: ItemStack): Unit = { + var superCall: () => Unit = () => super.setItemSlot(slotIn, stack) + if (slotIn == EquipmentSlotType.MAINHAND) { + agent.equipmentInventory.setItem(0, stack) superCall = () => { - val slot = inventory.currentItem - // So, if we're not in the main inventory, currentItem is set to -1 + val slot = inventory.selected + // So, if we're not in the main inventory, selected is set to -1 // for compatibility with mods that try accessing the inv directly - // using inventory.currentItem. See li.cil.oc.server.agent.Inventory - if(inventory.currentItem < 0) inventory.currentItem = ~inventory.currentItem - super.setItemStackToSlot(slotIn, stack) - inventory.currentItem = slot + // using inventory.selected. See li.cil.oc.server.agent.Inventory + if(inventory.selected < 0) inventory.selected = ~inventory.selected + super.setItemSlot(slotIn, stack) + inventory.selected = slot } - } else if(slotIn == EntityEquipmentSlot.OFFHAND) { - inventory.offHandInventory.set(0, stack) + } else if(slotIn == EquipmentSlotType.OFFHAND) { + inventory.offhand.set(0, stack) } superCall() } - override def getItemStackFromSlot(slotIn: EntityEquipmentSlot): ItemStack = { - if (slotIn == EntityEquipmentSlot.MAINHAND) - agent.equipmentInventory.getStackInSlot(0) - else if(slotIn == EntityEquipmentSlot.OFFHAND) - inventory.offHandInventory.get(0) - else super.getItemStackFromSlot(slotIn) + override def getItemBySlot(slotIn: EquipmentSlotType): ItemStack = { + if (slotIn == EquipmentSlotType.MAINHAND) + agent.equipmentInventory.getItem(0) + else if(slotIn == EquipmentSlotType.OFFHAND) + inventory.offhand.get(0) + else super.getItemBySlot(slotIn) } - def fireRightClickBlock(pos: BlockPos, side: EnumFacing): PlayerInteractEvent.RightClickBlock = { - val hitVec = new Vec3d(0.5 + side.getDirectionVec.getX * 0.5, 0.5 + side.getDirectionVec.getY * 0.5, 0.5 + side.getDirectionVec.getZ * 0.5) - val event = new PlayerInteractEvent.RightClickBlock(this, EnumHand.OFF_HAND, pos, side, hitVec) + def fireRightClickBlock(pos: BlockPos, side: Direction): PlayerInteractEvent.RightClickBlock = { + val hitVec = new Vector3d(0.5 + side.getStepX * 0.5, 0.5 + side.getStepY * 0.5, 0.5 + side.getStepZ * 0.5) + val event = new PlayerInteractEvent.RightClickBlock(this, Hand.OFF_HAND, pos, new BlockRayTraceResult(hitVec, side, pos, false)) MinecraftForge.EVENT_BUS.post(event) event } - def fireLeftClickBlock(pos: BlockPos, side: EnumFacing): PlayerInteractEvent.LeftClickBlock = { - val hitVec = new Vec3d(0.5 + side.getDirectionVec.getX * 0.5, 0.5 + side.getDirectionVec.getY * 0.5, 0.5 + side.getDirectionVec.getZ * 0.5) - net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this, pos, side, hitVec) + def fireLeftClickBlock(pos: BlockPos, side: Direction): PlayerInteractEvent.LeftClickBlock = { + net.minecraftforge.common.ForgeHooks.onLeftClickBlock(this, pos, side) } def fireRightClickAir(): PlayerInteractEvent.RightClickItem = { - val event = new PlayerInteractEvent.RightClickItem(this, EnumHand.OFF_HAND) + val event = new PlayerInteractEvent.RightClickItem(this, Hand.OFF_HAND) MinecraftForge.EVENT_BUS.post(event) event } private def trySetActiveHand(duration: Double): Boolean = { - stopActiveHand() + releaseUsingItem() val entity = this val durationHandler = new { @SubscribeEvent(priority = EventPriority.LOWEST) @@ -328,8 +351,8 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc } MinecraftForge.EVENT_BUS.register(durationHandler) try { - setActiveHand(EnumHand.OFF_HAND) - isHandActive + startUsingItem(Hand.OFF_HAND) + isUsingItem } catch { case _: Exception => false } finally { @@ -349,25 +372,25 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc return false } - val maxDuration = stack.getMaxItemUseDuration + val maxDuration = stack.getUseDuration val heldTicks = Math.max(0, Math.min(maxDuration, (duration * 20).toInt)) agent.machine.pause(heldTicks / 20.0) // setting the active hand will also set its initial duration - val useItemResult = stack.useItemRightClick(world, this, EnumHand.OFF_HAND) - stopActiveHand() + val useItemResult = stack.use(level, this, Hand.OFF_HAND) + releaseUsingItem() - if (useItemResult.getType != EnumActionResult.SUCCESS) { + if (!useItemResult.getResult.consumesAction) { return false } - val newStack = useItemResult.getResult + val newStack = useItemResult.getObject val stackChanged: Boolean = - !ItemStack.areItemStacksEqual(oldStack, newStack) || - !ItemStack.areItemStacksEqual(oldStack, stack) + !ItemStack.matches(oldStack, newStack) || + !ItemStack.matches(oldStack, stack) if (stackChanged) { - inventory.offHandInventory.set(0, newStack) + inventory.offhand.set(0, newStack) } stackChanged } @@ -386,19 +409,17 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc // Change the offset at which items are used, to avoid hitting // the robot itself (e.g. with bows, potions, mining laser, ...). - posX += facing.getFrontOffsetX / 2.0 - posZ += facing.getFrontOffsetZ / 2.0 + setPos(getX + facing.getStepX / 2.0, getY, getZ + facing.getStepZ / 2.0) try { useItemWithHand(duration, stackOption.get) } finally { - posX -= facing.getFrontOffsetX / 2.0 - posZ -= facing.getFrontOffsetZ / 2.0 + setPos(getX - facing.getStepX / 2.0, getY, getZ - facing.getStepZ / 2.0) } } - def placeBlock(slot: Int, pos: BlockPos, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = { + def placeBlock(slot: Int, pos: BlockPos, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Boolean = { callUsingItemInSlot(agent.mainInventory, slot, stack => { if (shouldCancel(() => fireRightClickBlock(pos, side))) { return false @@ -408,14 +429,14 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc }, repair = false) } - def clickBlock(pos: BlockPos, side: EnumFacing): Double = callUsingItemInSlot(agent.equipmentInventory, 0, stack => { - val state = world.getBlockState(pos) + def clickBlock(pos: BlockPos, side: Direction): Double = callUsingItemInSlot(agent.equipmentInventory, 0, stack => { + val state = level.getBlockState(pos) val block = state.getBlock - if (!block.canHarvestBlock(world, pos, this)) return 0 + if (!state.canHarvestBlock(level, pos, this)) return 0 - val hardness = block.getBlockHardness(state, world, pos) - val cobwebOverride = block == Blocks.WEB && Settings.get.screwCobwebs + val hardness = state.getDestroySpeed(level, pos) + val cobwebOverride = block == Blocks.COBWEB && Settings.get.screwCobwebs val strength = getDigSpeed(state, pos) val breakTime = @@ -425,13 +446,13 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc if (breakTime.isInfinity) return 0 if (breakTime < 0) return breakTime - val preEvent = new RobotBreakBlockEvent.Pre(agent, world, pos, breakTime * Settings.get.harvestRatio) + val preEvent = new RobotBreakBlockEvent.Pre(agent, level, pos, breakTime * Settings.get.harvestRatio) MinecraftForge.EVENT_BUS.post(preEvent) if (preEvent.isCanceled) return 0 val adjustedBreakTime = Math.max(0.05, preEvent.getBreakTime) if (!PlayerInteractionManagerHelper.onBlockClicked(this, pos, side)) { - if (world.isAirBlock(pos)) { + if (level.isEmptyBlock(pos)) { return 1.0 / 20.0 } return 0 @@ -443,10 +464,10 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc }) private def isItemUseAllowed(stack: ItemStack) = stack.isEmpty || { - (Settings.get.allowUseItemsWithDuration || stack.getMaxItemUseDuration <= 0) && !stack.isItemEqual(new ItemStack(Items.LEAD)) + (Settings.get.allowUseItemsWithDuration || stack.getUseDuration <= 0) && !stack.sameItem(new ItemStack(Items.LEAD)) } - override def dropItem(stack: ItemStack, dropAround: Boolean, traceItem: Boolean): EntityItem = + override def drop(stack: ItemStack, dropAround: Boolean, traceItem: Boolean): ItemEntity = InventoryUtils.spawnStackInWorld(BlockPosition(agent), stack, if (dropAround) None else Option(facing)) private def shouldCancel(f: () => PlayerInteractEvent) = { @@ -470,34 +491,34 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc private def callUsingItemInSlot[T](inventory: IInventory, slot: Int, f: ItemStack => T, repair: Boolean = true) = { val itemsBefore = adjacentItems - val stack = inventory.getStackInSlot(slot) + val stack = inventory.getItem(slot) val oldStack = stack.copy() - this.inventory.currentItem = if (inventory == agent.mainInventory) slot else ~slot - this.inventory.offHandInventory.set(0, inventory.getStackInSlot(slot)) + this.inventory.selected = if (inventory == agent.mainInventory) slot else ~slot + this.inventory.offhand.set(0, inventory.getItem(slot)) try { f(stack) } finally { - this.inventory.currentItem = 0 - inventory.setInventorySlotContents(slot, this.inventory.offHandInventory.get(0)) - this.inventory.offHandInventory.set(0, ItemStack.EMPTY) - val newStack = inventory.getStackInSlot(slot) + this.inventory.selected = 0 + inventory.setItem(slot, this.inventory.offhand.get(0)) + this.inventory.offhand.set(0, ItemStack.EMPTY) + val newStack = inventory.getItem(slot) // this is only possible if f() modified the stack object in-place // looking at you, ic2 - if (ItemStack.areItemStacksEqual(oldStack, newStack) && - !ItemStack.areItemStacksEqual(oldStack, stack)) { - inventory.setInventorySlotContents(slot, stack) + if (ItemStack.matches(oldStack, newStack) && + !ItemStack.matches(oldStack, stack)) { + inventory.setItem(slot, stack) } if (!newStack.isEmpty) { if (newStack.getCount <= 0) { - inventory.setInventorySlotContents(slot, ItemStack.EMPTY) + inventory.setItem(slot, ItemStack.EMPTY) } if (repair) { if (newStack.getCount > 0) tryRepair(newStack, oldStack) - else ForgeEventFactory.onPlayerDestroyItem(this, newStack, EnumHand.OFF_HAND) + else ForgeEventFactory.onPlayerDestroyItem(this, newStack, Hand.OFF_HAND) } } - collectDroppedItems(itemsBefore) + collectDroppedItems(itemsBefore.asScala) } } @@ -512,37 +533,40 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc } } - private def tryPlaceBlockWhileHandlingFunnySpecialCases(stack: ItemStack, pos: BlockPos, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = { + private def tryPlaceBlockWhileHandlingFunnySpecialCases(stack: ItemStack, pos: BlockPos, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = { !stack.isEmpty && stack.getCount > 0 && { - val event = new RobotPlaceBlockEvent.Pre(agent, stack, world, pos) + val event = new RobotPlaceBlockEvent.Pre(agent, stack, level, pos) MinecraftForge.EVENT_BUS.post(event) if (event.isCanceled) false else { - val fakeEyeHeight = if (rotationPitch < 0 && isSomeKindOfPiston(stack)) 1.82 else 0 - setPosition(posX, posY - fakeEyeHeight, posZ) - Player.setInventoryPlayerItems(this) - val didPlace = stack.onItemUse(this, world, pos, EnumHand.OFF_HAND, side, hitX, hitY, hitZ) - Player.detectInventoryPlayerChanges(this) - setPosition(posX, posY + fakeEyeHeight, posZ) - if (didPlace == EnumActionResult.SUCCESS) { - MinecraftForge.EVENT_BUS.post(new RobotPlaceBlockEvent.Post(agent, stack, world, pos)) + val fakeEyeHeight = if (xRot < 0 && isSomeKindOfPiston(stack)) 1.82 else 0 + setPos(getX, getY - fakeEyeHeight, getZ) + Player.setPlayerInventoryItems(this) + val state = level.getBlockState(pos) + val traceEndPos = new Vector3d(pos.getX + hitX, pos.getY + hitY, pos.getZ + hitZ) + val traceCtx = if (state.getBlock.isAir(state, level, pos)) BlockRayTraceResult.miss(traceEndPos, side, pos) else new BlockRayTraceResult(traceEndPos, side, pos, false) + val didPlace = stack.useOn(new ItemUseContext(level, this, Hand.OFF_HAND, stack, traceCtx)) + Player.detectPlayerInventoryChanges(this) + setPos(getX, getY + fakeEyeHeight, getZ) + if (didPlace.consumesAction) { + MinecraftForge.EVENT_BUS.post(new RobotPlaceBlockEvent.Post(agent, stack, level, pos)) } - didPlace == EnumActionResult.SUCCESS + didPlace.consumesAction } } } private def isSomeKindOfPiston(stack: ItemStack) = stack.getItem match { - case itemBlock: ItemBlock => + case itemBlock: BlockItem => val block = itemBlock.getBlock - block != null && block.isInstanceOf[BlockPistonBase] + block != null && block.isInstanceOf[PistonBlock] case _ => false } // ----------------------------------------------------------------------- // - override def addExhaustion(amount: Float) { + override def causeFoodExhaustion(amount: Float) { if (Settings.get.robotExhaustionCost > 0) { agent.machine.node match { case connector: Connector => connector.changeBuffer(-Settings.get.robotExhaustionCost * amount) @@ -552,80 +576,72 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc MinecraftForge.EVENT_BUS.post(new RobotExhaustionEvent(agent, amount)) } - override def closeScreen() {} + override def closeContainer() {} - override def swingArm(hand: EnumHand): Unit = {} + override def swing(hand: Hand): Unit = {} - override def canUseCommand(level: Int, command: String): Boolean = { - ("seed" == command && !mcServer.isDedicatedServer) || - "tell" == command || - "help" == command || - "me" == command || { - val config = mcServer.getPlayerList - config.canSendCommands(getGameProfile) && { - config.getOppedPlayers.getEntry(getGameProfile) match { - case opEntry: UserListOpsEntry => opEntry.getPermissionLevel >= level - case _ => mcServer.getOpPermissionLevel >= level - } + override protected def getPermissionLevel: Int = { + val config = server.getPlayerList + if (config.isOp(getGameProfile)) { + config.getOps.get(getGameProfile) match { + case opEntry: OpEntry => opEntry.getLevel + case _ => server.getOperatorUserPermissionLevel } } + else 0 } - override def canAttackPlayer(player: EntityPlayer): Boolean = Settings.get.canAttackPlayers + override def canHarmPlayer(player: PlayerEntity): Boolean = Settings.get.canAttackPlayers override def canEat(value: Boolean) = false - override def isPotionApplicable(effect: PotionEffect) = false + override def canBeAffected(effect: EffectInstance) = false - override def attackEntityAsMob(entity: Entity) = false + override def doHurtTarget(entity: Entity) = false - override def attackEntityFrom(source: DamageSource, damage: Float) = false + override def hurt(source: DamageSource, damage: Float) = false override def heal(amount: Float) {} override def setHealth(value: Float) {} - override def setDead(): Unit = isDead = true + override def remove(invalidate: Boolean): Unit = super.remove(false) - override def onLivingUpdate() {} + override def aiStep() {} - override def onItemPickup(entity: Entity, count: Int) {} + override def take(entity: Entity, count: Int) {} - override def setRevengeTarget(entity: EntityLivingBase) {} + override def setLastHurtByMob(entity: LivingEntity) {} - override def setLastAttackedEntity(entity: Entity) {} + override def setLastHurtMob(entity: Entity) {} override def startRiding(entityIn: Entity, force: Boolean): Boolean = false - override def trySleep(bedLocation: BlockPos) = SleepResult.OTHER_PROBLEM - - override def sendMessage(message: ITextComponent) {} + override def startSleepInBed(bedLocation: BlockPos) = Either.left[SleepResult, net.minecraft.util.Unit](SleepResult.OTHER_PROBLEM) - override def displayGUIChest(inventory: IInventory) {} + override def sendMessage(message: ITextComponent, sender: UUID) {} - override def displayGuiCommandBlock(commandBlock: TileEntityCommandBlock): Unit = {} + override def openCommandBlock(commandBlock: CommandBlockTileEntity): Unit = {} - override def displayVillagerTradeGui(villager: IMerchant): Unit = { - villager.setCustomer(null) - } + override def sendMerchantOffers(containerId: Int, offers: MerchantOffers, villagerLevel: Int, villagerXP: Int, showProgress: Boolean, canRestock: Boolean): Unit = {} - override def displayGui(guiOwner: IInteractionObject) {} + override def openMenu(guiOwner: INamedContainerProvider) = util.OptionalInt.empty - override def displayGuiEditCommandCart(thing: CommandBlockBaseLogic): Unit = {} + override def openMinecartCommandBlock(thing: CommandBlockLogic): Unit = {} - override def openEditSign(signTile: TileEntitySign) {} + override def openTextEdit(signTile: SignTileEntity) {} // ----------------------------------------------------------------------- // - class DamageOverTime(val player: Player, val pos: BlockPos, val side: EnumFacing, val ticksTotal: Int) { - val world: World = player.world + class DamageOverTime(val player: Player, val pos: BlockPos, val side: Direction, val ticksTotal: Int) { + val level: World = player.level var ticks = 0 var lastDamageSent = 0 def tick(): Unit = { // Cancel if the agent stopped or our action is invalidated some other way. - if (world != player.world || !world.isBlockLoaded(pos) || world.isAirBlock(pos) || !player.agent.machine.isRunning) { - player.interactionManager.cancelDestroyingBlock() + if (level != player.level || !level.isLoaded(pos) || level.isEmptyBlock(pos) || !player.agent.machine.isRunning) { + player.gameMode.handleBlockBreakAction(pos, CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, side, 0) return } @@ -641,11 +657,9 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc } else { callUsingItemInSlot(player.agent.equipmentInventory(), 0, _ => { - this.player.posX -= side.getFrontOffsetX / 2.0 - this.player.posZ -= side.getFrontOffsetZ / 2.0 + this.player.setPos(this.player.getX - side.getStepX / 2.0, this.player.getY, this.player.getZ - side.getStepZ / 2.0) val expGained: Int = PlayerInteractionManagerHelper.blockRemoving(player, pos) - this.player.posX += side.getFrontOffsetX / 2.0 - this.player.posZ += side.getFrontOffsetZ / 2.0 + this.player.setPos(this.player.getX + side.getStepX / 2.0, this.player.getY, this.player.getZ + side.getStepZ / 2.0) if (expGained >= 0) { MinecraftForge.EVENT_BUS.post(new RobotBreakBlockEvent.Post(agent, expGained)) } diff --git a/src/main/scala/li/cil/oc/server/agent/PlayerInteractionManagerHelper.scala b/src/main/scala/li/cil/oc/server/agent/PlayerInteractionManagerHelper.scala index 25351a95ed..0137b32864 100644 --- a/src/main/scala/li/cil/oc/server/agent/PlayerInteractionManagerHelper.scala +++ b/src/main/scala/li/cil/oc/server/agent/PlayerInteractionManagerHelper.scala @@ -1,6 +1,7 @@ package li.cil.oc.server.agent -import net.minecraft.util.EnumFacing +import net.minecraft.network.play.client.CPlayerDiggingPacket +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import li.cil.oc.OpenComputers import li.cil.oc.api.network.Node @@ -9,32 +10,33 @@ import net.minecraftforge.common.MinecraftForge import net.minecraftforge.event.entity.player.PlayerEvent import net.minecraftforge.event.world.BlockEvent import net.minecraftforge.fml.common.ObfuscationReflectionHelper -import net.minecraftforge.fml.common.eventhandler.{EventPriority, SubscribeEvent} +import net.minecraftforge.eventbus.api.{EventPriority, SubscribeEvent} -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object PlayerInteractionManagerHelper { + private val isDestroyingBlock = ObfuscationReflectionHelper.findField(classOf[PlayerInteractionManager], "field_73088_d") private def isDestroyingBlock(player: Player): Boolean = { try { - ObfuscationReflectionHelper.getPrivateValue(classOf[PlayerInteractionManager], player.interactionManager, "isDestroyingBlock", "field_73088_d").asInstanceOf[Boolean] + isDestroyingBlock.getBoolean(player.gameMode) } catch { case _: Exception => true } } - def onBlockClicked(player: Player, pos: BlockPos, side: EnumFacing): Boolean = { + def onBlockClicked(player: Player, pos: BlockPos, side: Direction): Boolean = { if (isDestroyingBlock(player)) { - player.interactionManager.cancelDestroyingBlock() + player.gameMode.handleBlockBreakAction(pos, CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, side, 0) } - player.interactionManager.onBlockClicked(pos, side) + player.gameMode.handleBlockBreakAction(pos, CPlayerDiggingPacket.Action.START_DESTROY_BLOCK, side, 0) isDestroyingBlock(player) } def updateBlockRemoving(player: Player): Boolean = { if (!isDestroyingBlock(player)) return false - player.interactionManager.updateBlockRemoving() + player.gameMode.tick() isDestroyingBlock(player) } @@ -61,7 +63,7 @@ object PlayerInteractionManagerHelper { @SubscribeEvent(priority = EventPriority.LOWEST) def onBreakSpeedEvent(breakSpeedEvent: PlayerEvent.BreakSpeed): Unit = { - if (player == breakSpeedEvent.getEntityPlayer) + if (player == breakSpeedEvent.getPlayer) breakSpeedEvent.setNewSpeed(scala.Float.MaxValue) } @@ -78,12 +80,12 @@ object PlayerInteractionManagerHelper { MinecraftForge.EVENT_BUS.register(infBreaker) try { - player.interactionManager.blockRemoving(pos) + player.gameMode.handleBlockBreakAction(pos, CPlayerDiggingPacket.Action.STOP_DESTROY_BLOCK, null, 0) infBreaker.expToDrop } catch { case e: Exception => { OpenComputers.log.info(s"an exception was thrown while trying to call blockRemoving: ${e.getMessage}") - player.interactionManager.cancelDestroyingBlock() + player.gameMode.handleBlockBreakAction(pos, CPlayerDiggingPacket.Action.ABORT_DESTROY_BLOCK, null, 0) -1 } } finally { diff --git a/src/main/scala/li/cil/oc/server/command/CommandHandler.scala b/src/main/scala/li/cil/oc/server/command/CommandHandler.scala deleted file mode 100644 index 0ca8790be2..0000000000 --- a/src/main/scala/li/cil/oc/server/command/CommandHandler.scala +++ /dev/null @@ -1,15 +0,0 @@ -package li.cil.oc.server.command - -import net.minecraftforge.fml.common.event.FMLServerStartingEvent - -object CommandHandler { - def register(e: FMLServerStartingEvent) { - e.registerServerCommand(DebugNanomachinesCommand) - e.registerServerCommand(LogNanomachinesCommand) - e.registerServerCommand(NonDisassemblyAgreementCommand) - e.registerServerCommand(WirelessRenderingCommand) - e.registerServerCommand(SpawnComputerCommand) - e.registerServerCommand(DebugWhitelistCommand) - e.registerServerCommand(SendDebugMessageCommand) - } -} diff --git a/src/main/scala/li/cil/oc/server/command/DebugNanomachinesCommand.scala b/src/main/scala/li/cil/oc/server/command/DebugNanomachinesCommand.scala deleted file mode 100644 index 5f7f1d972d..0000000000 --- a/src/main/scala/li/cil/oc/server/command/DebugNanomachinesCommand.scala +++ /dev/null @@ -1,37 +0,0 @@ -package li.cil.oc.server.command - -import li.cil.oc.api -import li.cil.oc.common.command.SimpleCommand -import li.cil.oc.common.nanomachines.ControllerImpl -import net.minecraft.command.ICommandSender -import net.minecraft.command.WrongUsageException -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.server.MinecraftServer -import net.minecraft.util.text.TextComponentString - -object DebugNanomachinesCommand extends SimpleCommand("oc_debugNanomachines") { - aliases += "oc_dn" - - override def getUsage(source: ICommandSender): String = name - - override def execute(server: MinecraftServer, source: ICommandSender, args: Array[String]): Unit = { - source match { - case player: EntityPlayer => - api.Nanomachines.installController(player) match { - case controller: ControllerImpl => - controller.debug() - player.sendMessage(new TextComponentString("Debug configuration created, see log for mappings.")) - case _ => // Someone did something. - } - case _ => throw new WrongUsageException("Can only be used by players.") - } - } - - // OP levels for reference: - // 1 - Ops can bypass spawn protection. - // 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks. - // 3 - Ops can use /ban, /deop, /kick, and /op. - // 4 - Ops can use /stop. - - override def getRequiredPermissionLevel = 2 -} diff --git a/src/main/scala/li/cil/oc/server/command/DebugWhitelistCommand.scala b/src/main/scala/li/cil/oc/server/command/DebugWhitelistCommand.scala deleted file mode 100644 index 3927c87617..0000000000 --- a/src/main/scala/li/cil/oc/server/command/DebugWhitelistCommand.scala +++ /dev/null @@ -1,54 +0,0 @@ -package li.cil.oc.server.command - -import li.cil.oc.Settings -import li.cil.oc.Settings.DebugCardAccess -import li.cil.oc.common.command.SimpleCommand -import net.minecraft.command.{ICommandSender, WrongUsageException} -import net.minecraft.server.MinecraftServer -import net.minecraft.util.text.TextComponentString - -object DebugWhitelistCommand extends SimpleCommand("oc_debugWhitelist") { - // Required OP levels: - // to revoke your cards - 0 - // to do other whitelist manipulation - 2 - - override def getRequiredPermissionLevel = 0 - private def isOp(sender: ICommandSender) = getOpLevel(sender) >= 2 - - override def getUsage(sender: ICommandSender): String = - if (isOp(sender)) name + " [revoke|add|remove] OR " + name + " [revoke|list]" - else name + " revoke" - - override def execute(server: MinecraftServer, sender: ICommandSender, args: Array[String]): Unit = { - val wl = Settings.get.debugCardAccess match { - case w: DebugCardAccess.Whitelist => w - case _ => throw new WrongUsageException("§cDebug card whitelisting is not enabled.") - } - - def revokeUser(player: String): Unit = { - if (wl.isWhitelisted(player)) { - wl.invalidate(player) - sender.sendMessage(new TextComponentString("§aAll your debug cards were invalidated.")) - } else sender.sendMessage(new TextComponentString("§cYou are not whitelisted to use debug card.")) - } - - args match { - case Array("revoke") => revokeUser(sender.getName) - case Array("revoke", player) if isOp(sender) => revokeUser(player) - case Array("list") if isOp(sender) => - val players = wl.whitelist - if (players.nonEmpty) - sender.sendMessage(new TextComponentString("§aCurrently whitelisted players: §e" + players.mkString(", "))) - else - sender.sendMessage(new TextComponentString("§cThere is no currently whitelisted players.")) - case Array("add", player) if isOp(sender) => - wl.add(player) - sender.sendMessage(new TextComponentString("§aPlayer was added to whitelist.")) - case Array("remove", player) if isOp(sender) => - wl.remove(player) - sender.sendMessage(new TextComponentString("§aPlayer was removed from whitelist")) - case _ => - sender.sendMessage(new TextComponentString("§e" + getUsage(sender))) - } - } -} diff --git a/src/main/scala/li/cil/oc/server/command/LogNanomachinesCommand.scala b/src/main/scala/li/cil/oc/server/command/LogNanomachinesCommand.scala deleted file mode 100644 index 8f859eb786..0000000000 --- a/src/main/scala/li/cil/oc/server/command/LogNanomachinesCommand.scala +++ /dev/null @@ -1,39 +0,0 @@ -package li.cil.oc.server.command - -import li.cil.oc.api -import li.cil.oc.common.command.SimpleCommand -import li.cil.oc.common.nanomachines.ControllerImpl -import net.minecraft.command.ICommandSender -import net.minecraft.command.WrongUsageException -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.server.MinecraftServer -import net.minecraftforge.fml.common.FMLCommonHandler - -object LogNanomachinesCommand extends SimpleCommand("oc_nanomachines") { - aliases += "oc_nm" - - override def getUsage(source: ICommandSender): String = name + " [player]" - - override def execute(server: MinecraftServer, source: ICommandSender, command: Array[String]): Unit = { - (if (command.length > 0) { - val player = command(0) - val config = FMLCommonHandler.instance.getMinecraftServerInstance.getPlayerList - config.getPlayerByUsername(player) - } else source) match { - case player: EntityPlayer => - api.Nanomachines.installController(player) match { - case controller: ControllerImpl => controller.print() - case _ => // Someone did something. - } - case _ => throw new WrongUsageException("Player entity not found.") - } - } - - // OP levels for reference: - // 1 - Ops can bypass spawn protection. - // 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks. - // 3 - Ops can use /ban, /deop, /kick, and /op. - // 4 - Ops can use /stop. - - override def getRequiredPermissionLevel = 2 -} diff --git a/src/main/scala/li/cil/oc/server/command/NonDisassemblyAgreementCommand.scala b/src/main/scala/li/cil/oc/server/command/NonDisassemblyAgreementCommand.scala deleted file mode 100644 index 8812711dd9..0000000000 --- a/src/main/scala/li/cil/oc/server/command/NonDisassemblyAgreementCommand.scala +++ /dev/null @@ -1,49 +0,0 @@ -package li.cil.oc.server.command - -import li.cil.oc.Settings -import li.cil.oc.common.command.SimpleCommand -import net.minecraft.command.CommandBase -import net.minecraft.command.ICommandSender -import net.minecraft.command.WrongUsageException -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.server.MinecraftServer - -object NonDisassemblyAgreementCommand extends SimpleCommand("oc_preventDisassembling") { - aliases += "oc_nodis" - aliases += "oc_prevdis" - - override def getUsage(source: ICommandSender) = name + " " - - override def execute(server: MinecraftServer, source: ICommandSender, command: Array[String]): Unit = { - source match { - case player: EntityPlayer => - val stack = player.getHeldItemMainhand - if (!stack.isEmpty) { - if (!stack.hasTagCompound) { - stack.setTagCompound(new NBTTagCompound()) - } - val nbt = stack.getTagCompound - val preventDisassembly = - if (command != null && command.length > 0) - CommandBase.parseBoolean(command(0)) - else - !nbt.getBoolean(Settings.namespace + "undisassemblable") - if (preventDisassembly) - nbt.setBoolean(Settings.namespace + "undisassemblable", true) - else - nbt.removeTag(Settings.namespace + "undisassemblable") - if (nbt.hasNoTags) stack.setTagCompound(null) - } - case _ => throw new WrongUsageException("Can only be used by players.") - } - } - - // OP levels for reference: - // 1 - Ops can bypass spawn protection. - // 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks. - // 3 - Ops can use /ban, /deop, /kick, and /op. - // 4 - Ops can use /stop. - - override def getRequiredPermissionLevel = 2 -} diff --git a/src/main/scala/li/cil/oc/server/command/SendDebugMessageCommand.scala b/src/main/scala/li/cil/oc/server/command/SendDebugMessageCommand.scala deleted file mode 100644 index f6e600bfae..0000000000 --- a/src/main/scala/li/cil/oc/server/command/SendDebugMessageCommand.scala +++ /dev/null @@ -1,27 +0,0 @@ -package li.cil.oc.server.command - -import li.cil.oc.api.Network -import li.cil.oc.common.command.SimpleCommand -import li.cil.oc.server.network.DebugNetwork -import net.minecraft.command.ICommandSender -import net.minecraft.command.WrongUsageException -import net.minecraft.server.MinecraftServer - -object SendDebugMessageCommand extends SimpleCommand("oc_sendDebugMessage") { - aliases += "oc_sdbg" - - override def getUsage(sender: ICommandSender): String = name + " [message...]" - - override def execute(server: MinecraftServer, sender: ICommandSender, args: Array[String]): Unit = { - if (args == null || args.length == 0) { - throw new WrongUsageException("no destination address specified.") - } - val destination = args(0) - DebugNetwork.getEndpoint(destination).foreach { endpoint => - val packet = Network.newPacket(sender.getName, destination, 0, args.drop(1).toList.toArray[AnyRef]) - endpoint.receivePacket(packet) - } - } - - override def getRequiredPermissionLevel = 2 -} diff --git a/src/main/scala/li/cil/oc/server/command/SpawnComputerCommand.scala b/src/main/scala/li/cil/oc/server/command/SpawnComputerCommand.scala deleted file mode 100644 index d0738329bd..0000000000 --- a/src/main/scala/li/cil/oc/server/command/SpawnComputerCommand.scala +++ /dev/null @@ -1,101 +0,0 @@ -package li.cil.oc.server.command - -import li.cil.oc.Constants -import li.cil.oc.api -import li.cil.oc.common.command.SimpleCommand -import li.cil.oc.common.tileentity -import li.cil.oc.server.machine.luac.{LuaStateFactory, NativeLua53Architecture} -import li.cil.oc.util.BlockPosition -import li.cil.oc.util.ExtendedWorld._ -import li.cil.oc.util.InventoryUtils -import net.minecraft.command.ICommandSender -import net.minecraft.command.WrongUsageException -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.server.MinecraftServer -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.RayTraceResult -import net.minecraft.util.math.Vec3d -import net.minecraft.util.text.TextComponentString - -object SpawnComputerCommand extends SimpleCommand("oc_spawnComputer") { - aliases += "oc_sc" - - final val MaxDistance = 16 - - override def getUsage(source: ICommandSender): String = name - - override def execute(server: MinecraftServer, source: ICommandSender, command: Array[String]): Unit = { - source match { - case player: EntityPlayer => - val world = player.getEntityWorld - val origin = new Vec3d(player.posX, player.posY + player.getEyeHeight, player.posZ) - val direction = player.getLookVec - val lookAt = origin.addVector(direction.x * MaxDistance, direction.y * MaxDistance, direction.z * MaxDistance) - world.rayTraceBlocks(origin, lookAt) match { - case hit: RayTraceResult if hit.typeOfHit == RayTraceResult.Type.BLOCK => - val hitPos = BlockPosition(hit.getBlockPos, world) - val casePos = hitPos.offset(hit.sideHit) - val screenPos = casePos.offset(EnumFacing.UP) - val keyboardPos = screenPos.offset(EnumFacing.UP) - - if (!world.isAirBlock(casePos) || !world.isAirBlock(screenPos) || !world.isAirBlock(keyboardPos)) { - player.sendMessage(new TextComponentString("Target position obstructed.")) - return - } - - def rotateProperly(pos: BlockPosition):tileentity.traits.Rotatable = { - world.getTileEntity(pos) match { - case rotatable: tileentity.traits.Rotatable => - rotatable.setFromEntityPitchAndYaw(player) - if (!rotatable.validFacings.contains(rotatable.pitch)) { - rotatable.pitch = rotatable.validFacings.headOption.getOrElse(EnumFacing.NORTH) - } - rotatable.invertRotation() - rotatable - case _ => null // not rotatable - } - } - - world.setBlock(casePos, api.Items.get(Constants.BlockName.CaseCreative).block()) - rotateProperly(casePos) - world.setBlock(screenPos, api.Items.get(Constants.BlockName.ScreenTier2).block()) - rotateProperly(screenPos) match { - case rotatable: tileentity.traits.Rotatable => rotatable.pitch match { - case EnumFacing.UP | EnumFacing.DOWN => - rotatable.pitch = EnumFacing.NORTH - case _ => // nothing to do here, pitch is fine - } - case _ => // ??? - } - world.setBlock(keyboardPos, api.Items.get(Constants.BlockName.Keyboard).block()) - world.getTileEntity(keyboardPos) match { - case t: tileentity.traits.Rotatable => - t.setFromEntityPitchAndYaw(player) - t.setFromFacing(EnumFacing.UP) - case _ => // ??? - } - - api.Network.joinOrCreateNetwork(world.getTileEntity(casePos)) - - val apu = api.Items.get(Constants.ItemName.APUCreative).createItemStack(1) - LuaStateFactory.setDefaultArch(apu) - - InventoryUtils.insertIntoInventoryAt(apu, casePos) - InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.RAMTier6).createItemStack(2), casePos) - InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.HDDTier3).createItemStack(1), casePos) - InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.LuaBios).createItemStack(1), casePos) - InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.OpenOS).createItemStack(1), casePos) - case _ => player.sendMessage(new TextComponentString("You need to be looking at a nearby block.")) - } - case _ => throw new WrongUsageException("Can only be used by players.") - } - } - - // OP levels for reference: - // 1 - Ops can bypass spawn protection. - // 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks. - // 3 - Ops can use /ban, /deop, /kick, and /op. - // 4 - Ops can use /stop. - - override def getRequiredPermissionLevel = 2 -} diff --git a/src/main/scala/li/cil/oc/server/command/WirelessRenderingCommand.scala b/src/main/scala/li/cil/oc/server/command/WirelessRenderingCommand.scala deleted file mode 100644 index 22ff9226c4..0000000000 --- a/src/main/scala/li/cil/oc/server/command/WirelessRenderingCommand.scala +++ /dev/null @@ -1,29 +0,0 @@ -package li.cil.oc.server.command - -import li.cil.oc.Settings -import li.cil.oc.common.command.SimpleCommand -import net.minecraft.command.CommandBase -import net.minecraft.command.ICommandSender -import net.minecraft.server.MinecraftServer - -object WirelessRenderingCommand extends SimpleCommand("oc_renderWirelessNetwork") { - aliases += "oc_wlan" - - override def getUsage(source: ICommandSender) = name + " " - - override def execute(server: MinecraftServer, source: ICommandSender, command: Array[String]): Unit = { - Settings.rTreeDebugRenderer = - if (command != null && command.length > 0) - CommandBase.parseBoolean(command(0)) - else - !Settings.rTreeDebugRenderer - } - - // OP levels for reference: - // 1 - Ops can bypass spawn protection. - // 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks. - // 3 - Ops can use /ban, /deop, /kick, and /op. - // 4 - Ops can use /stop. - - override def getRequiredPermissionLevel = 2 -} diff --git a/src/main/scala/li/cil/oc/server/command/package.scala b/src/main/scala/li/cil/oc/server/command/package.scala deleted file mode 100644 index da29b81294..0000000000 --- a/src/main/scala/li/cil/oc/server/command/package.scala +++ /dev/null @@ -1,31 +0,0 @@ -package li.cil.oc.server - -import net.minecraft.command.ICommandSender -import net.minecraft.entity.player.EntityPlayerMP -import net.minecraft.server.MinecraftServer -import net.minecraft.util.text.ITextComponent -import net.minecraft.util.text.TextComponentString -import net.minecraftforge.fml.common.FMLCommonHandler - -import scala.language.implicitConversions - -package object command { - implicit def string2text(s: String): ITextComponent = new TextComponentString(s) - - def getOpLevel(sender: ICommandSender): Int = { - // Shitty minecraft server logic & shitty minecraft server code. - val srv = FMLCommonHandler.instance().getMinecraftServerInstance - if (srv.isSinglePlayer && srv.worlds.head.getWorldInfo.areCommandsAllowed && - srv.getServerOwner.equalsIgnoreCase(sender.getName) /* || srv.commandsAllowedForAll */ ) - return 4 - - sender match { - case _: MinecraftServer => 4 - case p: EntityPlayerMP => - - val e = srv.getPlayerList.getOppedPlayers.getEntry(p.getGameProfile) - if (e == null) 0 else e.getPermissionLevel - case _ => 0 - } - } -} diff --git a/src/main/scala/li/cil/oc/server/component/APU.scala b/src/main/scala/li/cil/oc/server/component/APU.scala index cb3e3a948e..51b918a347 100644 --- a/src/main/scala/li/cil/oc/server/component/APU.scala +++ b/src/main/scala/li/cil/oc/server/component/APU.scala @@ -7,7 +7,7 @@ import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute import li.cil.oc.api.driver.DeviceInfo.DeviceClass import li.cil.oc.Settings -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class APU(tier: Int) extends GraphicsCard(tier) { private final lazy val deviceInfo = Map( diff --git a/src/main/scala/li/cil/oc/server/component/Agent.scala b/src/main/scala/li/cil/oc/server/component/Agent.scala index ad49f74009..71a8cdef09 100644 --- a/src/main/scala/li/cil/oc/server/component/Agent.scala +++ b/src/main/scala/li/cil/oc/server/component/Agent.scala @@ -15,34 +15,38 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.InventoryUtils import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState +import net.minecraft.block.BlockState import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.item.EntityMinecart -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.Pose +import net.minecraft.entity.item.ItemEntity +import net.minecraft.entity.item.minecart.MinecartEntity +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory -import net.minecraft.util.EnumActionResult -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.BlockRayTraceResult +import net.minecraft.util.math.EntityRayTraceResult +import net.minecraft.util.math.RayTraceContext import net.minecraft.util.math.RayTraceResult -import net.minecraft.util.math.Vec3d +import net.minecraft.util.math.vector.Vector3d import net.minecraftforge.common.MinecraftForge -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ trait Agent extends traits.WorldControl with traits.InventoryControl with traits.InventoryWorldControl with traits.TankAware with traits.TankControl with traits.TankWorldControl { def agent: internal.Agent override def position = BlockPosition(agent) - override def fakePlayer: EntityPlayer = agent.player + override def fakePlayer: PlayerEntity = agent.player - protected def rotatedPlayer(facing: EnumFacing = agent.facing, side: EnumFacing = agent.facing): Player = { + protected def rotatedPlayer(facing: Direction = agent.facing, side: Direction = agent.facing): Player = { val player = agent.player.asInstanceOf[Player] Player.updatePositionAndRotation(player, facing, side) // no need to set inventory, calling agent.Player already did that - //Player.setInventoryPlayerItems(player) + //Player.setPlayerInventoryItems(player) player } @@ -89,7 +93,7 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits } else { // Always try the direction we're looking first. - Iterable(facing) ++ EnumFacing.values.filter(side => side != facing && side != facing.getOpposite).toIterable + Iterable(facing) ++ Direction.values.filter(side => side != facing && side != facing.getOpposite).toIterable } val sneaky = args.isBoolean(2) && args.checkBoolean(2) @@ -98,12 +102,12 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits } def attack(player: Player, entity: Entity) = { beginConsumeDrops(entity) - player.attackTargetEntityWithCurrentItem(entity) + player.attack(entity) // Mine carts have to be hit quickly in succession to break, so we click // until it breaks. But avoid an infinite loop... you never know. entity match { - case _: EntityMinecart => for (_ <- 0 until 10 if !entity.isDead) { - player.attackTargetEntityWithCurrentItem(entity) + case _: MinecartEntity => for (_ <- 0 until 10 if entity.isAlive) { + player.attack(entity) } case _ => } @@ -111,7 +115,7 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits triggerDelay() (true, "entity") } - def click(player: Player, pos: BlockPos, side: EnumFacing) = { + def click(player: Player, pos: BlockPos, side: Direction) = { val breakTime = player.clickBlock(pos, side) val broke = breakTime > 0 if (broke) { @@ -123,21 +127,22 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits var reason: Option[String] = None for (side <- sides) { val player = rotatedPlayer(facing, side) - player.setSneaking(sneaky) + player.setPose(if (sneaky) Pose.CROUCHING else Pose.STANDING) val (success, what) = { val hit = pick(player, Settings.get.swingRange) (Option(hit) match { - case Some(info) => info.typeOfHit + case Some(info) => info.getType case _ => RayTraceResult.Type.MISS }) match { case RayTraceResult.Type.ENTITY => - attack(player, hit.entityHit) + attack(player, hit.asInstanceOf[EntityRayTraceResult].getEntity) case RayTraceResult.Type.BLOCK => - click(player, hit.getBlockPos, hit.sideHit) + val blockHit = hit.asInstanceOf[BlockRayTraceResult] + click(player, blockHit.getBlockPos, blockHit.getDirection) case _ => // Retry with full block bounds, disregarding swing range. - player.closestEntity(classOf[EntityLivingBase]) match { + player.closestEntity(classOf[LivingEntity]) match { case Some(entity) => attack(player, entity) case _ => @@ -150,7 +155,7 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits } } - player.setSneaking(false) + player.setPose(Pose.STANDING) if (success) { return result(true, what) } @@ -162,9 +167,9 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits if (hasBlock) { val blockPos = position.offset(facing) val player = rotatedPlayer(facing, facing) - player.setSneaking(sneaky) + player.setPose(if (sneaky) Pose.CROUCHING else Pose.STANDING) val (ok, why) = click(player, blockPos.toBlockPos, facing) - player.setSneaking(false) + player.setPose(Pose.STANDING) return result(ok, why) } @@ -180,7 +185,7 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits } else { // Always try the direction we're looking first. - Iterable(facing) ++ EnumFacing.values.filter(side => side != facing && side != facing.getOpposite).toIterable + Iterable(facing) ++ Direction.values.filter(side => side != facing && side != facing.getOpposite).toIterable } val sneaky = args.isBoolean(2) && args.checkBoolean(2) val duration = @@ -205,22 +210,23 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits } def interact(player: Player, entity: Entity) = { beginConsumeDrops(entity) - val result = player.interactOn(entity, EnumHand.MAIN_HAND) + val result = player.interactOn(entity, Hand.MAIN_HAND) endConsumeDrops(player, entity) result } for (side <- sides) { val player = rotatedPlayer(facing, side) - player.setSneaking(sneaky) + player.setPose(if (sneaky) Pose.CROUCHING else Pose.STANDING) val (success, what) = Option(pick(player, Settings.get.useAndPlaceRange)) match { - case Some(hit) if hit.typeOfHit == RayTraceResult.Type.ENTITY && interact(player, hit.entityHit) == EnumActionResult.SUCCESS => + case Some(hit) if hit.getType == RayTraceResult.Type.ENTITY && interact(player, hit.asInstanceOf[EntityRayTraceResult].getEntity).consumesAction => triggerDelay() (true, "item_interacted") - case Some(hit) if hit.typeOfHit == RayTraceResult.Type.BLOCK => - val (blockPos, hx, hy, hz) = clickParamsFromHit(hit) - activationResult(player.activateBlockOrUseItem(blockPos, hit.sideHit, hx, hy, hz, duration)) + case Some(hit) if hit.getType == RayTraceResult.Type.BLOCK => + val blockHit = hit.asInstanceOf[BlockRayTraceResult] + val (blockPos, hx, hy, hz) = clickParamsFromHit(blockHit) + activationResult(player.activateBlockOrUseItem(blockPos, blockHit.getDirection, hx, hy, hz, duration)) case _ => (if (canPlaceInAir) { val (blockPos, hx, hy, hz) = clickParamsForPlace(facing) @@ -241,7 +247,7 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits } } - player.setSneaking(false) + player.setPose(Pose.STANDING) if (success) { return result(true, what) } @@ -259,41 +265,42 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits } else { // Always try the direction we're looking first. - Iterable(facing) ++ EnumFacing.values.filter(side => side != facing && side != facing.getOpposite).toIterable + Iterable(facing) ++ Direction.values.filter(side => side != facing && side != facing.getOpposite).toIterable } val sneaky = args.isBoolean(2) && args.checkBoolean(2) - val stack = agent.mainInventory.getStackInSlot(agent.selectedSlot) + val stack = agent.mainInventory.getItem(agent.selectedSlot) if (stack.isEmpty) { - return result(Unit, "nothing selected") + return result((), "nothing selected") } for (side <- sides) { val player = rotatedPlayer(facing, side) - player.setSneaking(sneaky) + player.setPose(if (sneaky) Pose.CROUCHING else Pose.STANDING) val success = Option(pick(player, Settings.get.useAndPlaceRange)) match { - case Some(hit) if hit.typeOfHit == RayTraceResult.Type.BLOCK => - val (blockPos, hx, hy, hz) = clickParamsFromHit(hit) - player.placeBlock(agent.selectedSlot, blockPos, hit.sideHit, hx, hy, hz) + case Some(hit) if hit.getType == RayTraceResult.Type.BLOCK => + val blockHit = hit.asInstanceOf[BlockRayTraceResult] + val (blockPos, hx, hy, hz) = clickParamsFromHit(blockHit) + player.placeBlock(agent.selectedSlot, blockPos, blockHit.getDirection, hx, hy, hz) case None if canPlaceInAir && player.closestEntity(classOf[Entity]).isEmpty => val (blockPos, hx, hy, hz) = clickParamsForPlace(facing) // blockPos here is the position of the agent - // When a robot uses angel placement, the ItemBlock code offsets the pos to EnumFacing + // When a robot uses angel placement, the BlockItem code offsets the pos to Direction // but for a drone, the block at its position is air, which is replaceable, and thus - // ItemBlock does not offset the position. We can do it here to correct that, and the code + // BlockItem does not offset the position. We can do it here to correct that, and the code // here is still correct for the robot's use case - val adjustedPos: BlockPos = blockPos.offset(facing) + val adjustedPos: BlockPos = blockPos.relative(facing) // adjustedPos is the position we want to place the block // but onItemUse will try to adjust the placement if the target position is not replaceable // we don't want that - val block: Block = world.getBlockState(adjustedPos).getBlock - if (block.isReplaceable(world, adjustedPos)) { + val state: BlockState = world.getBlockState(adjustedPos) + if (state.getMaterial.isReplaceable) { player.placeBlock(agent.selectedSlot, adjustedPos, facing, hx, hy, hz) } else { false } case _ => false } - player.setSneaking(false) + player.setPose(Pose.STANDING) if (success) { onWorldInteraction(context, Settings.get.placeDelay) return result(true) @@ -306,70 +313,69 @@ trait Agent extends traits.WorldControl with traits.InventoryControl with traits // ----------------------------------------------------------------------- // protected def beginConsumeDrops(entity: Entity) { - entity.captureDrops = true + entity.captureDrops(new java.util.ArrayList[ItemEntity]()) } protected def endConsumeDrops(player: Player, entity: Entity) { - entity.captureDrops = false + val captured = entity.captureDrops(null) // this inventory size check is a HACK to preserve old behavior that a agent can suck items out // of the capturedDrops. Ideally, we'd only pick up items off the ground. We could clear the - // capturedDrops when Player.attackTargetEntityWithCurrentItem() is called + // capturedDrops when Player.attack() is called // But this felt slightly less hacky, slightly - if (player.inventory.getSizeInventory > 0) { - for (drop <- entity.capturedDrops) { - if (!drop.isDead) { + if (player.inventory.getContainerSize > 0) { + for (drop <- captured) { + if (drop.isAlive) { val stack = drop.getItem InventoryUtils.addToPlayerInventory(stack, player, spawnInWorld = false) } } } - entity.capturedDrops.clear() } // ----------------------------------------------------------------------- // - protected def checkSideForFace(args: Arguments, n: Int, facing: EnumFacing): EnumFacing = agent.toGlobal(args.checkSideForFace(n, agent.toLocal(facing))) + protected def checkSideForFace(args: Arguments, n: Int, facing: Direction): Direction = agent.toGlobal(args.checkSideForFace(n, agent.toLocal(facing))) protected def pick(player: Player, range: Double): RayTraceResult = { - val origin = new Vec3d( - player.posX + player.facing.getFrontOffsetX * 0.5, - player.posY + player.facing.getFrontOffsetY * 0.5, - player.posZ + player.facing.getFrontOffsetZ * 0.5) - val blockCenter = origin.addVector( - player.facing.getFrontOffsetX * 0.51, - player.facing.getFrontOffsetY * 0.51, - player.facing.getFrontOffsetZ * 0.51) - val target = blockCenter.addVector( - player.side.getFrontOffsetX * range, - player.side.getFrontOffsetY * range, - player.side.getFrontOffsetZ * range) - val hit = world.rayTraceBlocks(origin, target) + val origin = new Vector3d( + player.getX + player.facing.getStepX * 0.5, + player.getY + player.facing.getStepY * 0.5, + player.getZ + player.facing.getStepZ * 0.5) + val blockCenter = origin.add( + player.facing.getStepX * 0.51, + player.facing.getStepY * 0.51, + player.facing.getStepZ * 0.51) + val target = blockCenter.add( + player.side.getStepX * range, + player.side.getStepY * range, + player.side.getStepZ * range) + val hit = world.clip(new RayTraceContext(origin, target, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.ANY, player)) player.closestEntity(classOf[Entity]) match { - case Some(entity@(_: EntityLivingBase | _: EntityMinecart | _: entity.Drone)) if hit == null || new Vec3d(player.posX, player.posY, player.posZ).distanceTo(hit.hitVec) > player.getDistance(entity) => new RayTraceResult(entity) + case Some(entity@(_: LivingEntity | _: MinecartEntity | _: entity.Drone)) if hit.getType == RayTraceResult.Type.MISS || player.distanceToSqr(hit.getLocation) > player.distanceToSqr(entity) => new EntityRayTraceResult(entity) case _ => hit } } - protected def clickParamsFromHit(hit: RayTraceResult): (BlockPos, Float, Float, Float) = { + protected def clickParamsFromHit(hit: BlockRayTraceResult): (BlockPos, Float, Float, Float) = { (hit.getBlockPos, - (hit.hitVec.x - hit.getBlockPos.getX).toFloat, - (hit.hitVec.y - hit.getBlockPos.getY).toFloat, - (hit.hitVec.z - hit.getBlockPos.getZ).toFloat) + (hit.getLocation.x - hit.getBlockPos.getX).toFloat, + (hit.getLocation.y - hit.getBlockPos.getY).toFloat, + (hit.getLocation.z - hit.getBlockPos.getZ).toFloat) } - protected def clickParamsForItemUse(facing: EnumFacing, side: EnumFacing): (BlockPos, Float, Float, Float) = { + protected def clickParamsForItemUse(facing: Direction, side: Direction): (BlockPos, Float, Float, Float) = { val blockPos = position.offset(facing).offset(side) (blockPos.toBlockPos, - 0.5f - side.getFrontOffsetX * 0.5f, - 0.5f - side.getFrontOffsetY * 0.5f, - 0.5f - side.getFrontOffsetZ * 0.5f) + 0.5f - side.getStepX * 0.5f, + 0.5f - side.getStepY * 0.5f, + 0.5f - side.getStepZ * 0.5f) } - protected def clickParamsForPlace(facing: EnumFacing): (BlockPos, Float, Float, Float) = { + protected def clickParamsForPlace(facing: Direction): (BlockPos, Float, Float, Float) = { (position.toBlockPos, - 0.5f + facing.getFrontOffsetX * 0.5f, - 0.5f + facing.getFrontOffsetY * 0.5f, - 0.5f + facing.getFrontOffsetZ * 0.5f) + 0.5f + facing.getStepX * 0.5f, + 0.5f + facing.getStepY * 0.5f, + 0.5f + facing.getStepZ * 0.5f) } } diff --git a/src/main/scala/li/cil/oc/server/component/CPU.scala b/src/main/scala/li/cil/oc/server/component/CPU.scala index ecaef64912..38168a887d 100644 --- a/src/main/scala/li/cil/oc/server/component/CPU.scala +++ b/src/main/scala/li/cil/oc/server/component/CPU.scala @@ -12,7 +12,7 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class CPU(val tier: Int) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Neighbors). diff --git a/src/main/scala/li/cil/oc/server/component/DataCard.scala b/src/main/scala/li/cil/oc/server/component/DataCard.scala index d7388906de..238098afc4 100644 --- a/src/main/scala/li/cil/oc/server/component/DataCard.scala +++ b/src/main/scala/li/cil/oc/server/component/DataCard.scala @@ -25,11 +25,11 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import org.apache.commons.codec.binary.Base64 import org.apache.commons.io.output.ByteArrayOutputStream -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ abstract class DataCard extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Neighbors). @@ -328,15 +328,15 @@ object DataCard { private final val TypeTag = "Type" private final val DataTag = "Data" - override def load(nbt: NBTTagCompound): Unit = { + override def loadData(nbt: CompoundNBT): Unit = { val keyType = nbt.getString(TypeTag) val data = nbt.getByteArray(DataTag) value = ECUserdata.deserializeKey(keyType, data) } - override def save(nbt: NBTTagCompound): Unit = { - nbt.setString(TypeTag, keyType) - nbt.setByteArray(DataTag, value.getEncoded) + override def saveData(nbt: CompoundNBT): Unit = { + nbt.putString(TypeTag, keyType) + nbt.putByteArray(DataTag, value.getEncoded) } } diff --git a/src/main/scala/li/cil/oc/server/component/DebugCard.scala b/src/main/scala/li/cil/oc/server/component/DebugCard.scala index bc5c7dba73..bf08bc698a 100644 --- a/src/main/scala/li/cil/oc/server/component/DebugCard.scala +++ b/src/main/scala/li/cil/oc/server/component/DebugCard.scala @@ -1,5 +1,8 @@ package li.cil.oc.server.component +import java.util.UUID +import java.util.function.Supplier + import com.google.common.base.Strings import li.cil.oc.OpenComputers import li.cil.oc.Settings @@ -20,7 +23,7 @@ import li.cil.oc.api.prefab.AbstractValue import li.cil.oc.server.PacketSender import li.cil.oc.server.network.DebugNetwork import li.cil.oc.server.network.DebugNetwork.DebugNode -import li.cil.oc.server.component.DebugCard.{AccessContext, CommandSender} +import li.cil.oc.server.component.DebugCard.AccessContext import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedBlock._ @@ -28,35 +31,46 @@ import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.InventoryUtils import net.minecraft.block.Block -import net.minecraft.command.CommandResultStats.Type -import net.minecraft.entity.item.EntityMinecart -import net.minecraft.entity.{Entity, EntityLivingBase} -import net.minecraft.entity.player.EntityPlayerMP +import net.minecraft.command.CommandSource +import net.minecraft.command.ICommandSource +import net.minecraft.entity.item.minecart.MinecartEntity +import net.minecraft.entity.{Entity, LivingEntity} +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.nbt._ -import net.minecraft.scoreboard.{IScoreCriteria, Scoreboard} -import net.minecraft.server.management.UserListOpsEntry +import net.minecraft.scoreboard.{ScoreCriteria, Scoreboard} +import net.minecraft.server.MinecraftServer import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.ResourceLocation +import net.minecraft.util.RegistryKey import net.minecraft.util.SoundCategory import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Vec3d +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.util.math.vector.Vector2f +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.util.registry.Registry import net.minecraft.util.text.ITextComponent -import net.minecraft.world.{GameType, World, WorldServer, WorldSettings} -import net.minecraftforge.common.{DimensionManager, MinecraftForge} +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.{GameType, World, WorldSettings} +import net.minecraft.world.server.ServerWorld +import net.minecraft.world.storage.IServerWorldInfo +import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayer import net.minecraftforge.common.util.FakePlayerFactory import net.minecraftforge.event.world.BlockEvent -import net.minecraftforge.fluids.FluidRegistry import net.minecraftforge.fluids.FluidStack +import net.minecraftforge.fluids.IFluidBlock import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.fml.common.FMLCommonHandler -import net.minecraftforge.fml.common.Loader -import net.minecraftforge.fml.common.ModAPIManager - -import scala.collection.convert.WrapAsScala._ +import net.minecraftforge.fml.ModList +import net.minecraftforge.fml.server.ServerLifecycleHooks +import net.minecraftforge.registries.ForgeRegistries +import net.minecraftforge.registries.ForgeRegistry +import net.minecraftforge.registries.IForgeRegistry + +import scala.collection.JavaConverters.{collectionAsScalaIterable, mapAsScalaMap} +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with DebugNode { @@ -76,12 +90,30 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D def player: Option[String] = access.map(_.player) - private lazy val CommandSender = { - def defaultFakePlayer = FakePlayerFactory.get(host.world.asInstanceOf[WorldServer], Settings.get.fakePlayerProfile) - new CommandSender(host, player match { - case Some(name) => Option(FMLCommonHandler.instance.getMinecraftServerInstance.getPlayerList.getPlayerByUsername(name)).getOrElse(defaultFakePlayer) + private var CommandMessages: Option[String] = None + + private def createCommandSourceStack(): CommandSource = { + val sender = new ICommandSource { + override def sendMessage(message: ITextComponent, sender: UUID) { + CommandMessages = Option(CommandMessages.fold("")(_ + "\n") + message.getString) + } + + override def acceptsSuccess = true + + override def acceptsFailure = true + + override def shouldInformAdmins = true + } + val world = host.world.asInstanceOf[ServerWorld] + val server = world.getServer + def defaultFakePlayer = FakePlayerFactory.get(world, Settings.get.fakePlayerProfile) + val sourcePlayer = player match { + case Some(name) => Option(server.getPlayerList.getPlayerByName(name)).getOrElse(defaultFakePlayer) case _ => defaultFakePlayer - }) + } + val permLevel = server.getProfilePermissions(sourcePlayer.getGameProfile) + new CommandSource(sender, new Vector3d(host.xPosition, host.yPosition, host.zPosition), Vector2f.ZERO, world, + permLevel, sourcePlayer.getName.getString, sourcePlayer.getDisplayName, server, sourcePlayer) } // ----------------------------------------------------------------------- // @@ -112,17 +144,28 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D result(host.zPosition) } + @Deprecated @Callback(doc = """function([id:number]):userdata -- Get the world object for the specified dimension ID, or the container's.""") def getWorld(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - if (args.count() > 0) result(new DebugCard.WorldValue(DimensionManager.getWorld(args.checkInteger(0)))) + if (args.count() > 0) { + val server = ServerLifecycleHooks.getCurrentServer + val world = args.checkInteger(0) match { + case 0 => server.overworld + case -1 => server.getLevel(World.NETHER) + case 1 => server.getLevel(World.END) + case _ => null + } + result(new DebugCard.WorldValue(world)) + } else result(new DebugCard.WorldValue(host.world)) } + @Deprecated @Callback(doc = """function():table -- Get a list of all world IDs, loaded and unloaded.""") def getWorlds(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(DimensionManager.getStaticDimensionIDs) + result(Array[Int](0, -1, 1)) } @Callback(doc = """function(name:string):userdata -- Get the entity of a player.""") @@ -134,7 +177,7 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D @Callback(doc = """function():table -- Get a list of currently logged-in players.""") def getPlayers(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(FMLCommonHandler.instance.getMinecraftServerInstance.getOnlinePlayerNames) + result(ServerLifecycleHooks.getCurrentServer.getPlayerNames) } @Callback(doc = """function():userdata -- Get the scoreboard object for the world""") @@ -144,41 +187,46 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D } + @Deprecated @Callback(doc = "function(x: number, y: number, z: number[, worldId: number]):boolean, string, table -- returns contents at the location in world by id (default host world)") def scanContentsAt(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val x = args.checkInteger(0) val y = args.checkInteger(1) val z = args.checkInteger(2) - val worldServer = if (args.count() > 3) DimensionManager.getWorld(args.checkInteger(3)) else host.world - val world = worldServer.world + val server = ServerLifecycleHooks.getCurrentServer + val world = if (args.count() > 3) args.checkInteger(3) match { + case 0 => server.overworld + case -1 => server.getLevel(World.NETHER) + case 1 => server.getLevel(World.END) + case _ => null + } else host.world val position: BlockPosition = new BlockPosition(x, y, z, Option(world)) - val fakePlayer = FakePlayerFactory.get(world.asInstanceOf[WorldServer], Settings.get.fakePlayerProfile) - fakePlayer.posX = position.x + 0.5 - fakePlayer.posY = position.y + 0.5 - fakePlayer.posZ = position.z + 0.5 - - Option(world.findNearestEntityWithinAABB(classOf[Entity], position.bounds, fakePlayer)) match { - case Some(living: EntityLivingBase) => result(true, "EntityLivingBase", living) - case Some(minecart: EntityMinecart) => result(true, "EntityMinecart", minecart) + val fakePlayer = FakePlayerFactory.get(world.asInstanceOf[ServerWorld], Settings.get.fakePlayerProfile) + fakePlayer.setPos(position.x + 0.5, position.y + 0.5, position.z + 0.5) + + val candidates = world.getEntitiesOfClass(classOf[Entity], position.bounds, null) + (if (!candidates.isEmpty) Some(candidates.minBy(fakePlayer.distanceToSqr(_))) else None) match { + case Some(living: LivingEntity) => result(true, "EntityLiving", living) + case Some(minecart: MinecartEntity) => result(true, "EntityMinecart", minecart) case _ => - val block = world.getBlock(position) - val metadata = world.getBlockMetadata(position) - if (block.isAir(position)) { + val state = world.getBlockState(position.toBlockPos) + val block = state.getBlock + if (block.isAir(state, world, position.toBlockPos)) { result(false, "air", block) } - else if (FluidRegistry.lookupFluidForBlock(block) != null) { - val event = new BlockEvent.BreakEvent(world, position.toBlockPos, metadata, fakePlayer) + else if (!block.isInstanceOf[IFluidBlock]) { + val event = new BlockEvent.BreakEvent(world, position.toBlockPos, state, fakePlayer) MinecraftForge.EVENT_BUS.post(event) result(event.isCanceled, "liquid", block) } else if (block.isReplaceable(position)) { - val event = new BlockEvent.BreakEvent(world, position.toBlockPos, metadata, fakePlayer) + val event = new BlockEvent.BreakEvent(world, position.toBlockPos, state, fakePlayer) MinecraftForge.EVENT_BUS.post(event) result(event.isCanceled, "replaceable", block) } - else if (block.getCollisionBoundingBoxFromPool(position) == null) { + else if (state.getCollisionShape(world, position.toBlockPos, ISelectionContext.empty).isEmpty) { result(true, "passable", block) } else { @@ -191,7 +239,7 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D def isModLoaded(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val name = args.checkString(0) - result(Loader.isModLoaded(name) || ModAPIManager.INSTANCE.hasAPI(name)) + result(ModList.get.isLoaded(name)) } @Callback(doc = """function(command:string):number -- Runs an arbitrary command using a fake player.""") @@ -201,13 +249,14 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D if (args.isTable(0)) collectionAsScalaIterable(args.checkTable(0).values()) else Iterable(args.checkString(0)) - CommandSender.synchronized { - CommandSender.prepare() + val source = createCommandSourceStack + CommandMessages.synchronized { + CommandMessages = None var value = 0 for (command <- commands) { - value = FMLCommonHandler.instance.getMinecraftServerInstance.getCommandManager.executeCommand(CommandSender, command.toString) + value = ServerLifecycleHooks.getCurrentServer.getCommands.performCommand(source, command.toString) } - result(value, CommandSender.messages.orNull) + result(value, CommandMessages.orNull) } } @@ -225,14 +274,14 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D node.connect(other) result(true) case _ => - result(Unit, "no node found at this position") + result((), "no node found at this position") } } private def findNode(position: BlockPosition) = if (host.world.blockExists(position)) { - host.world.getTileEntity(position) match { - case env: SidedEnvironment => EnumFacing.values.map(env.sidedNode).find(_ != null) + host.world.getBlockEntity(position) match { + case env: SidedEnvironment => Direction.values.map(env.sidedNode).find(_ != null) case env: Environment => Option(env.node) case _ => None } @@ -255,7 +304,7 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D @Callback(doc = """function(player:string, text:string) -- Sends text to the specified player's clipboard if possible.""") def sendToClipboard(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - Option(FMLCommonHandler.instance.getMinecraftServerInstance.getPlayerList.getPlayerByUsername(args.checkString(0))) match { + Option(ServerLifecycleHooks.getCurrentServer.getPlayerList.getPlayerByName(args.checkString(0))) match { case Some(player) => PacketSender.sendClipboard(player, args.checkString(1)) result(true) @@ -313,25 +362,25 @@ class DebugCard(host: EnvironmentHost) extends AbstractManagedEnvironment with D // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound): Unit = { - super.load(nbt) - access = AccessContext.load(nbt) - if (nbt.hasKey(Settings.namespace + "remoteX")) { - val x = nbt.getInteger(Settings.namespace + "remoteX") - val y = nbt.getInteger(Settings.namespace + "remoteY") - val z = nbt.getInteger(Settings.namespace + "remoteZ") + override def loadData(nbt: CompoundNBT): Unit = { + super.loadData(nbt) + access = AccessContext.loadData(nbt) + if (nbt.contains(Settings.namespace + "remoteX")) { + val x = nbt.getInt(Settings.namespace + "remoteX") + val y = nbt.getInt(Settings.namespace + "remoteY") + val z = nbt.getInt(Settings.namespace + "remoteZ") remoteNodePosition = Some((x, y, z)) } } - override def save(nbt: NBTTagCompound): Unit = { - super.save(nbt) - access.foreach(_.save(nbt)) + override def saveData(nbt: CompoundNBT): Unit = { + super.saveData(nbt) + access.foreach(_.saveData(nbt)) remoteNodePosition.foreach { case (x, y, z) => - nbt.setInteger(Settings.namespace + "remoteX", x) - nbt.setInteger(Settings.namespace + "remoteY", y) - nbt.setInteger(Settings.namespace + "remoteZ", z) + nbt.putInt(Settings.namespace + "remoteX", x) + nbt.putInt(Settings.namespace + "remoteY", y) + nbt.putInt(Settings.namespace + "remoteZ", z) } } } @@ -342,13 +391,13 @@ object DebugCard { throw new Exception(msg) object AccessContext { - def remove(nbt: NBTTagCompound): Unit = { - nbt.removeTag(Settings.namespace + "player") - nbt.removeTag(Settings.namespace + "accessNonce") + def remove(nbt: CompoundNBT): Unit = { + nbt.remove(Settings.namespace + "player") + nbt.remove(Settings.namespace + "accessNonce") } - def load(nbt: NBTTagCompound): Option[AccessContext] = { - if (nbt.hasKey(Settings.namespace + "player")) + def loadData(nbt: CompoundNBT): Option[AccessContext] = { + if (nbt.contains(Settings.namespace + "player")) Some(AccessContext( nbt.getString(Settings.namespace + "player"), nbt.getString(Settings.namespace + "accessNonce") @@ -359,9 +408,9 @@ object DebugCard { } case class AccessContext(player: String, nonce: String) { - def save(nbt: NBTTagCompound): Unit = { - nbt.setString(Settings.namespace + "player", player) - nbt.setString(Settings.namespace + "accessNonce", nonce) + def saveData(nbt: CompoundNBT): Unit = { + nbt.putString(Settings.namespace + "player", player) + nbt.putString(Settings.namespace + "accessNonce", nonce) } } @@ -370,39 +419,39 @@ object DebugCard { // ----------------------------------------------------------------------- // - def withPlayer(f: (EntityPlayerMP) => Array[AnyRef]): Array[AnyRef] = { + def withPlayer(f: (ServerPlayerEntity) => Array[AnyRef]): Array[AnyRef] = { checkAccess() - FMLCommonHandler.instance.getMinecraftServerInstance.getPlayerList.getPlayerByUsername(name) match { - case player: EntityPlayerMP => f(player) - case _ => result(Unit, "player is offline") + ServerLifecycleHooks.getCurrentServer.getPlayerList.getPlayerByName(name) match { + case player: ServerPlayerEntity => f(player) + case _ => result((), "player is offline") } } @Callback(doc = """function():userdata -- Get the player's world object.""") def getWorld(context: Context, args: Arguments): Array[AnyRef] = { - withPlayer(player => result(new DebugCard.WorldValue(player.getEntityWorld))) + withPlayer(player => result(new DebugCard.WorldValue(player.level))) } @Callback(doc = """function():string -- Get the player's game type.""") def getGameType(context: Context, args: Arguments): Array[AnyRef] = - withPlayer(player => result(player.interactionManager.getGameType.getName)) + withPlayer(player => result(player.gameMode.getGameModeForPlayer.getName)) @Callback(doc = """function(gametype:string) -- Set the player's game type (survival, creative, adventure).""") def setGameType(context: Context, args: Arguments): Array[AnyRef] = withPlayer(player => { val gametype = args.checkString(0) - player.setGameType(GameType.values.find(_.getName == gametype).getOrElse(GameType.SURVIVAL)) + player.gameMode.updateGameMode(GameType.byName(gametype, GameType.SURVIVAL)) null }) @Callback(doc = """function():number, number, number -- Get the player's position.""") def getPosition(context: Context, args: Arguments): Array[AnyRef] = - withPlayer(player => result(player.posX, player.posY, player.posZ)) + withPlayer(player => result(player.getX, player.getY, player.getZ)) @Callback(doc = """function(x:number, y:number, z:number) -- Set the player's position.""") def setPosition(context: Context, args: Arguments): Array[AnyRef] = withPlayer(player => { - player.setPositionAndUpdate(args.checkDouble(0), args.checkDouble(1), args.checkDouble(2)) + player.teleportTo(args.checkDouble(0), args.checkDouble(1), args.checkDouble(2)) null }) @@ -427,42 +476,43 @@ object DebugCard { @Callback(doc = """function():number -- Get the player's total experience""") def getExperienceTotal(context: Context, args: Arguments): Array[AnyRef] = - withPlayer(player => result(player.experienceTotal)) + withPlayer(player => result(player.totalExperience)) @Callback(doc = """function(level:number) -- Add a level to the player's experience level""") def addExperienceLevel(context: Context, args: Arguments): Array[AnyRef] = withPlayer(player => { - player.addExperienceLevel(args.checkInteger(0)) + player.giveExperienceLevels(args.checkInteger(0)) null }) @Callback(doc = """function(level:number) -- Remove a level from the player's experience level""") def removeExperienceLevel(context: Context, args: Arguments): Array[AnyRef] = withPlayer(player => { - player.addExperienceLevel(-args.checkInteger(0)) + player.giveExperienceLevels(-args.checkInteger(0)) null }) @Callback(doc = """function() -- Clear the players inventory""") def clearInventory(context: Context, args: Arguments): Array[AnyRef] = withPlayer(player => { - player.inventory.clear() + player.inventory.clearContent() null }) + @Deprecated @Callback(doc = """function(id:string, amount:number, meta:number[, nbt:string]):number -- Adds the item stack to the players inventory""") def insertItem(context: Context, args: Arguments): Array[AnyRef] = withPlayer(player => { - val item = Item.REGISTRY.getObject(new ResourceLocation(args.checkString(0))) + val item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(args.checkString(0))) if (item == null) { throw new IllegalArgumentException("invalid item id") } val amount = args.checkInteger(1) - val meta = args.checkInteger(2) + args.checkInteger(2) // meta val tagJson = args.checkString(3) - val tag = if (Strings.isNullOrEmpty(tagJson)) null else JsonToNBT.getTagFromJson(tagJson) - val stack = new ItemStack(item, amount, meta) - stack.setTagCompound(tag) + val tag = if (Strings.isNullOrEmpty(tagJson)) null else JsonToNBT.parseTag(tagJson) + val stack = new ItemStack(item, amount) + stack.setTag(tag) result(InventoryUtils.addToPlayerInventory(stack, player)) }) @@ -470,22 +520,22 @@ object DebugCard { private final val NameTag = "name" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - ctx = AccessContext.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + ctx = AccessContext.loadData(nbt) name = nbt.getString(NameTag) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - ctx.foreach(_.save(nbt)) - nbt.setString(NameTag, name) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + ctx.foreach(_.saveData(nbt)) + nbt.putString(NameTag, name) } } class ScoreboardValue(world: Option[World])(implicit var ctx: Option[AccessContext]) extends prefab.AbstractValue { var scoreboard: Scoreboard = world.fold(null: Scoreboard)(_.getScoreboard) - var dimension: Int = world.fold(0)(_.provider.getDimension) + var dimension: ResourceLocation = world.fold(World.OVERWORLD)(_.dimension).location def this() = this(None)(None) // For loading. @@ -493,7 +543,7 @@ object DebugCard { def addTeam(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val team = args.checkString(0) - scoreboard.createTeam(team) + scoreboard.addPlayerTeam(team) null } @@ -501,8 +551,8 @@ object DebugCard { def removeTeam(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val teamName = args.checkString(0) - val team = scoreboard.getTeam(teamName) - scoreboard.removeTeam(team) + val team = scoreboard.getPlayersTeam(teamName) + scoreboard.removePlayerTeam(team) null } @@ -510,7 +560,8 @@ object DebugCard { def addPlayerToTeam(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val player = args.checkString(0) - val team = args.checkString(1) + val teamName = args.checkString(1) + val team = scoreboard.getPlayersTeam(teamName) result(scoreboard.addPlayerToTeam(player, team)) } @@ -518,7 +569,7 @@ object DebugCard { def removePlayerFromTeams(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val player = args.checkString(0) - result(scoreboard.removePlayerFromTeams(player)) + result(scoreboard.removePlayerFromTeam(player)) } @Callback(doc = """function(player:string, team:string):boolean - Remove a player from a specific team""") @@ -527,7 +578,7 @@ object DebugCard { checkAccess() val player = args.checkString(0) val teamName = args.checkString(1) - val team = scoreboard.getTeam(teamName) + val team = scoreboard.getPlayersTeam(teamName) scoreboard.removePlayerFromTeam(player, team) null } @@ -537,8 +588,10 @@ object DebugCard { checkAccess() val objName = args.checkString(0) val objType = args.checkString(1) - val criteria = IScoreCriteria.INSTANCES.get(objType) - scoreboard.addScoreObjective(objName, criteria) + val criteria = ScoreCriteria.byName(objType).orElseThrow(new Supplier[IllegalArgumentException] { + override def get = new IllegalArgumentException("invalid criterion") + }) + scoreboard.addObjective(objName, criteria, new StringTextComponent(objName), ScoreCriteria.RenderType.INTEGER) null } @@ -557,8 +610,8 @@ object DebugCard { val name = args.checkString(0) val objective = scoreboard.getObjective(args.checkString(1)) val scoreVal = args.checkInteger(2) - val score = scoreboard.getOrCreateScore(name,objective) - score.setScorePoints(scoreVal) + val score = scoreboard.getOrCreatePlayerScore(name,objective) + score.setScore(scoreVal) null } @@ -567,8 +620,8 @@ object DebugCard { checkAccess() val name = args.checkString(0) val objective = scoreboard.getObjective(args.checkString(1)) - val score = scoreboard.getOrCreateScore(name, objective) - result(score.getScorePoints) + val score = scoreboard.getOrCreatePlayerScore(name, objective) + result(score.getScore) } @Callback(doc = """function(playerName:string, objectiveName:string, score:int) - Increases the score of a player for a certain objective""") @@ -577,8 +630,8 @@ object DebugCard { val name = args.checkString(0) val objective = scoreboard.getObjective(args.checkString(1)) val scoreVal = args.checkInteger(2) - val score = scoreboard.getOrCreateScore(name,objective) - score.increaseScore(scoreVal) + val score = scoreboard.getOrCreatePlayerScore(name,objective) + score.add(scoreVal) null } @@ -588,8 +641,8 @@ object DebugCard { val name = args.checkString(0) val objective = scoreboard.getObjective(args.checkString(1)) val scoreVal = args.checkInteger(2) - val score = scoreboard.getOrCreateScore(name,objective) - score.decreaseScore(scoreVal) + val score = scoreboard.getOrCreatePlayerScore(name,objective) + score.add(-scoreVal) null } @@ -598,17 +651,18 @@ object DebugCard { private final val DimensionTag = "dimension" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - ctx = AccessContext.load(nbt) - dimension = nbt.getInteger(DimensionTag) - scoreboard = DimensionManager.getWorld(dimension).getScoreboard + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + ctx = AccessContext.loadData(nbt) + dimension = new ResourceLocation(nbt.getString(DimensionTag)) + val dimKey = RegistryKey.create(Registry.DIMENSION_REGISTRY, dimension) + scoreboard = ServerLifecycleHooks.getCurrentServer.getLevel(dimKey).getScoreboard } - override def save(nbt: NBTTagCompound): Unit = { - super.save(nbt) - ctx.foreach(_.save(nbt)) - nbt.setInteger(DimensionTag, dimension) + override def saveData(nbt: CompoundNBT): Unit = { + super.saveData(nbt) + ctx.foreach(_.saveData(nbt)) + nbt.putString(DimensionTag, dimension.toString) } } @@ -618,22 +672,35 @@ object DebugCard { // ----------------------------------------------------------------------- // + @Deprecated @Callback(doc = """function():number -- Gets the numeric id of the current dimension.""") def getDimensionId(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.provider.getDimension) + world.dimension match { + case World.OVERWORLD => result(Int.box(0)) + case World.NETHER => result(Int.box(-1)) + case World.END => result(Int.box(1)) + case _ => throw new Error("deprecated") + } } + @Deprecated @Callback(doc = """function():string -- Gets the name of the current dimension.""") def getDimensionName(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.provider.getDimensionType.getName) + result(world.dimension.location.toString) + } + + @Callback(doc = """function():string -- Gets the resource location of the current dimension.""") + def getDimension(context: Context, args: Arguments): Array[AnyRef] = { + checkAccess() + result(world.dimension.location.toString) } @Callback(doc = """function():number -- Gets the seed of the world.""") def getSeed(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.getSeed) + result(world.asInstanceOf[ServerWorld].getSeed) } @Callback(doc = """function():boolean -- Returns whether it is currently raining.""") @@ -645,7 +712,7 @@ object DebugCard { @Callback(doc = """function(value:boolean) -- Sets whether it is currently raining.""") def setRaining(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - world.getWorldInfo.setRaining(args.checkBoolean(0)) + world.getLevelData.setRaining(args.checkBoolean(0)) null } @@ -658,33 +725,39 @@ object DebugCard { @Callback(doc = """function(value:boolean) -- Sets whether it is currently thundering.""") def setThundering(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - world.getWorldInfo.setThundering(args.checkBoolean(0)) + world.getLevelData.asInstanceOf[IServerWorldInfo].setThundering(args.checkBoolean(0)) null } @Callback(doc = """function():number -- Get the current world time.""") def getTime(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.getWorldTime) + result(world.getDayTime) } @Callback(doc = """function(value:number) -- Set the current world time.""") def setTime(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - world.setWorldTime(args.checkDouble(0).toLong) + world.asInstanceOf[ServerWorld].setDayTime(args.checkDouble(0).toLong) null } @Callback(doc = """function():number, number, number -- Get the current spawn point coordinates.""") def getSpawnPoint(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.getWorldInfo.getSpawnX, world.getWorldInfo.getSpawnY, world.getWorldInfo.getSpawnZ) + result(world.getLevelData.getXSpawn, world.getLevelData.getYSpawn, world.getLevelData.getZSpawn) } @Callback(doc = """function(x:number, y:number, z:number) -- Set the spawn point coordinates.""") def setSpawnPoint(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - world.getWorldInfo.setSpawn(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) + val x = args.checkInteger(0) + val y = args.checkInteger(1) + val z = args.checkInteger(2) + val info = world.getLevelData.asInstanceOf[IServerWorldInfo] + info.setXSpawn(x) + info.setYSpawn(y) + info.setZSpawn(z) null } @@ -700,34 +773,38 @@ object DebugCard { // ----------------------------------------------------------------------- // + @Deprecated @Callback(doc = """function(x:number, y:number, z:number):number -- Get the ID of the block at the specified coordinates.""") def getBlockId(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(Block.getIdFromBlock(world.getBlockState(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))).getBlock)) + val block = world.getBlockState(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))).getBlock + result(ForgeRegistries.BLOCKS.asInstanceOf[ForgeRegistry[Block]].getID(block)) } + @Deprecated @Callback(doc = """function(x:number, y:number, z:number):number -- Get the metadata of the block at the specified coordinates.""") def getMetadata(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - val state = world.getBlockState(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2))) - result(state.getBlock.getMetaFromState(state)) + args.checkInteger(0) + args.checkInteger(1) + args.checkInteger(2) + result(0) } + @Deprecated @Callback(doc = """function(x:number, y:number, z:number[, actualState:boolean=false]) - gets the block state for the block at the specified position, optionally getting additional display related data""") def getBlockState(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val pos = new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) var state = world.getBlockState(pos) - if (args.optBoolean(3, false)) { - state = state.getActualState(world, pos) - } + args.optBoolean(3, false) // actualState result(state) } @Callback(doc = """function(x:number, y:number, z:number):number -- Check whether the block at the specified coordinates is loaded.""") def isLoaded(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.isBlockLoaded(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)))) + result(world.isLoaded(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)))) } @Callback(doc = """function(x:number, y:number, z:number):number -- Check whether the block at the specified coordinates has a tile entity.""") @@ -735,15 +812,15 @@ object DebugCard { checkAccess() val blockPos = new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) val state = world.getBlockState(blockPos) - result(state.getBlock.hasTileEntity(state)) + result(state.hasTileEntity) } @Callback(doc = """function(x:number, y:number, z:number):table -- Get the NBT of the block at the specified coordinates.""") def getTileNBT(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val blockPos = new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) - world.getTileEntity(blockPos) match { - case tileEntity: TileEntity => result(toNbt((nbt) => tileEntity.writeToNBT(nbt): Unit).toTypedMap) + world.getBlockEntity(blockPos) match { + case tileEntity: TileEntity => result(toNbt((nbt) => tileEntity.save(nbt)).toTypedMap) case _ => null } } @@ -752,57 +829,70 @@ object DebugCard { def setTileNBT(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val blockPos = new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) - world.getTileEntity(blockPos) match { + val state = world.getBlockState(blockPos) + world.getBlockEntity(blockPos) match { case tileEntity: TileEntity => typedMapToNbt(mapAsScalaMap(args.checkTable(3)).toMap) match { - case nbt: NBTTagCompound => - tileEntity.readFromNBT(nbt) - tileEntity.markDirty() + case nbt: CompoundNBT => + tileEntity.load(state, nbt) + tileEntity.setChanged() world.notifyBlockUpdate(blockPos) result(true) - case nbt => result(Unit, s"nbt tag compound expected, got '${NBTBase.NBT_TYPES(nbt.getId)}'") + case nbt => result((), s"nbt tag COMPOUND expected, got 'nbt.getType.getName'") } - case _ => result(Unit, "no tile entity") + case _ => result((), "no tile entity") } } @Callback(doc = """function(x:number, y:number, z:number):number -- Get the light opacity of the block at the specified coordinates.""") def getLightOpacity(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.getBlockLightOpacity(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)))) + val pos = new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) + val state = world.getBlockState(pos) + result(state.getLightBlock(world, pos)) } @Callback(doc = """function(x:number, y:number, z:number):number -- Get the light value (emission) of the block at the specified coordinates.""") def getLightValue(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.getLight(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)), false)) + result(world.getLightEmission(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)))) } @Callback(doc = """function(x:number, y:number, z:number):number -- Get whether the block at the specified coordinates is directly under the sky.""") def canSeeSky(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - result(world.canBlockSeeSky(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)))) + result(world.canSeeSkyFromBelowWater(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)))) } + @Deprecated + private def getStateFromMeta(block: Block, meta: Int) = { + val states = block.getStateDefinition.getPossibleStates + if (meta >= 0 && meta < states.size) states.get(meta) else block.defaultBlockState + } + + @Deprecated @Callback(doc = """function(x:number, y:number, z:number, id:number or string, meta:number):number -- Set the block at the specified coordinates.""") def setBlock(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - val block = if (args.isInteger(3)) Block.getBlockById(args.checkInteger(3)) else Block.getBlockFromName(args.checkString(3)) + val registry = ForgeRegistries.BLOCKS.asInstanceOf[ForgeRegistry[Block]] + val block = if (args.isInteger(3)) registry.getValue(args.checkInteger(3)) else registry.getValue(new ResourceLocation(args.checkString(3))) val metadata = args.checkInteger(4) - result(world.setBlockState(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)), block.getStateFromMeta(metadata))) + result(world.setBlockAndUpdate(new BlockPos(args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)), getStateFromMeta(block, metadata))) } + @Deprecated @Callback(doc = """function(x1:number, y1:number, z1:number, x2:number, y2:number, z2:number, id:number or string, meta:number):number -- Set all blocks in the area defined by the two corner points (x1, y1, z1) and (x2, y2, z2).""") def setBlocks(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() val (xMin, yMin, zMin) = (args.checkInteger(0), args.checkInteger(1), args.checkInteger(2)) val (xMax, yMax, zMax) = (args.checkInteger(3), args.checkInteger(4), args.checkInteger(5)) - val block = if (args.isInteger(6)) Block.getBlockById(args.checkInteger(6)) else Block.getBlockFromName(args.checkString(6)) + val registry = ForgeRegistries.BLOCKS.asInstanceOf[ForgeRegistry[Block]] + val block = if (args.isInteger(3)) registry.getValue(args.checkInteger(3)) else registry.getValue(new ResourceLocation(args.checkString(3))) val metadata = args.checkInteger(7) for (x <- math.min(xMin, xMax) to math.max(xMin, xMax)) { for (y <- math.min(yMin, yMax) to math.max(yMin, yMax)) { for (z <- math.min(zMin, zMax) to math.max(zMin, zMax)) { - world.setBlockState(new BlockPos(x, y, z), block.getStateFromMeta(metadata)) + world.setBlockAndUpdate(new BlockPos(x, y, z), getStateFromMeta(block, metadata)) } } } @@ -811,25 +901,27 @@ object DebugCard { // ----------------------------------------------------------------------- // + @Deprecated @Callback(doc = """function(id:string, count:number, damage:number, nbt:string, x:number, y:number, z:number, side:number):boolean - Insert an item stack into the inventory at the specified location. NBT tag is expected in JSON format.""") def insertItem(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - val item = Item.REGISTRY.getObject(new ResourceLocation(args.checkString(0))) + val item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(args.checkString(0))) if (item == null) { throw new IllegalArgumentException("invalid item id") } val count = args.checkInteger(1) val damage = args.checkInteger(2) val tagJson = args.optString(3, "") - val tag = if (Strings.isNullOrEmpty(tagJson)) null else JsonToNBT.getTagFromJson(tagJson) + val tag = if (Strings.isNullOrEmpty(tagJson)) null else JsonToNBT.parseTag(tagJson) val position = BlockPosition(args.checkDouble(4), args.checkDouble(5), args.checkDouble(6), world) val side = args.checkSideAny(7) InventoryUtils.inventoryAt(position, side) match { case Some(inventory) => - val stack = new ItemStack(item, count, damage) - stack.setTagCompound(tag) + val stack = new ItemStack(item, count) + stack.setTag(tag) + stack.setDamageValue(damage) result(InventoryUtils.insertIntoInventory(stack, inventory)) - case _ => result(Unit, "no inventory") + case _ => result((), "no inventory") } } @@ -844,23 +936,23 @@ object DebugCard { val removed = inventory.extractItem(slot, count, false) if (removed.isEmpty) result(0) else result(removed.getCount) - case _ => result(Unit, "no inventory") + case _ => result((), "no inventory") } } @Callback(doc = """function(id:string, amount:number, x:number, y:number, z:number, side:number):boolean - Insert some fluid into the tank at the specified location.""") def insertFluid(context: Context, args: Arguments): Array[AnyRef] = { checkAccess() - val fluid = FluidRegistry.getFluid(args.checkString(0)) + val fluid = ForgeRegistries.FLUIDS.getValue(new ResourceLocation(args.checkString(0))) if (fluid == null) { throw new IllegalArgumentException("invalid fluid id") } val amount = args.checkInteger(1) val position = BlockPosition(args.checkDouble(2), args.checkDouble(3), args.checkDouble(4), world) val side = args.checkSideAny(5) - world.getTileEntity(position) match { - case handler: IFluidHandler => result(handler.fill(new FluidStack(fluid, amount), true)) - case _ => result(Unit, "no tank") + world.getBlockEntity(position) match { + case handler: IFluidHandler => result(handler.fill(new FluidStack(fluid, amount), IFluidHandler.FluidAction.EXECUTE)) + case _ => result((), "no tank") } } @@ -870,9 +962,9 @@ object DebugCard { val amount = args.checkInteger(0) val position = BlockPosition(args.checkDouble(1), args.checkDouble(2), args.checkDouble(3), world) val side = args.checkSideAny(4) - world.getTileEntity(position) match { - case handler: IFluidHandler => result(handler.drain(amount, true)) - case _ => result(Unit, "no tank") + world.getBlockEntity(position) match { + case handler: IFluidHandler => result(handler.drain(amount, IFluidHandler.FluidAction.EXECUTE)) + case _ => result((), "no tank") } } @@ -881,59 +973,19 @@ object DebugCard { private final val DimensionTag = "dimension" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - ctx = AccessContext.load(nbt) - world = DimensionManager.getWorld(nbt.getInteger(DimensionTag)) - } - - override def save(nbt: NBTTagCompound) { - super.save(nbt) - ctx.foreach(_.save(nbt)) - nbt.setInteger(DimensionTag, world.provider.getDimension) - } - } - - class CommandSender(val host: EnvironmentHost, val underlying: EntityPlayerMP) extends FakePlayer(underlying.getEntityWorld.asInstanceOf[WorldServer], underlying.getGameProfile) { - var messages: Option[String] = None - - def prepare(): Unit = { - val blockPos = BlockPosition(host) - posX = blockPos.x - posY = blockPos.y - posZ = blockPos.z - messages = None + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + ctx = AccessContext.loadData(nbt) + val dimension = new ResourceLocation(nbt.getString(DimensionTag)) + val dimKey = RegistryKey.create(Registry.DIMENSION_REGISTRY, dimension) + world = ServerLifecycleHooks.getCurrentServer.getLevel(dimKey) } - override def getName: String = underlying.getName - - override def getEntityWorld: World = host.world - - override def sendMessage(message: ITextComponent) { - messages = Option(messages.fold("")(_ + "\n") + message.getUnformattedText) - } - - override def getDisplayName: ITextComponent = underlying.getDisplayName - - override def setCommandStat(`type`: Type, amount: Int): Unit = underlying.setCommandStat(`type`, amount) - - override def getPosition: BlockPos = underlying.getPosition - - override def canUseCommand(level: Int, commandName: String): Boolean = { - val profile = underlying.getGameProfile - val server = underlying.mcServer - val config = server.getPlayerList - server.isSinglePlayer || (config.canSendCommands(profile) && (config.getOppedPlayers.getEntry(profile) match { - case entry: UserListOpsEntry => entry.getPermissionLevel >= level - case _ => server.getOpPermissionLevel >= level - })) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + ctx.foreach(_.saveData(nbt)) + nbt.putString(DimensionTag, world.dimension.location.toString) } - - override def getCommandSenderEntity: EntityPlayerMP = underlying - - override def getPositionVector: Vec3d = underlying.getPositionVector - - override def sendCommandFeedback(): Boolean = underlying.sendCommandFeedback() } class TestValue extends AbstractValue { @@ -961,14 +1013,14 @@ object DebugCard { private final val ValueTag = "value" - override def load(nbt: NBTTagCompound): Unit = { - super.load(nbt) + override def loadData(nbt: CompoundNBT): Unit = { + super.loadData(nbt) value = nbt.getString(ValueTag) } - override def save(nbt: NBTTagCompound): Unit = { - super.save(nbt) - nbt.setString(ValueTag, value) + override def saveData(nbt: CompoundNBT): Unit = { + super.saveData(nbt) + nbt.putString(ValueTag, value) } } diff --git a/src/main/scala/li/cil/oc/server/component/DiskDriveMountable.scala b/src/main/scala/li/cil/oc/server/component/DiskDriveMountable.scala index 1ce4946a14..400d54a14d 100644 --- a/src/main/scala/li/cil/oc/server/component/DiskDriveMountable.scala +++ b/src/main/scala/li/cil/oc/server/component/DiskDriveMountable.scala @@ -19,21 +19,27 @@ import li.cil.oc.api.network.Node import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import li.cil.oc.common.{GuiType, Slot, Sound} +import li.cil.oc.common.{Slot, Sound} +import li.cil.oc.common.container.ContainerTypes +import li.cil.oc.common.container.{DiskDrive => DiskDriveContainer} import li.cil.oc.common.inventory.ComponentInventory import li.cil.oc.common.inventory.ItemStackInventory import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.InventoryUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.entity.player.ServerPlayerEntity +import net.minecraft.inventory.container.INamedContainerProvider import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraft.util.Hand +import net.minecraft.util.text.StringTextComponent -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ -class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends AbstractManagedEnvironment with ItemStackInventory with ComponentInventory with RackMountable with Analyzable with DeviceInfo { +class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends AbstractManagedEnvironment with ItemStackInventory with ComponentInventory with RackMountable with Analyzable with DeviceInfo with INamedContainerProvider { // Stored for filling data packet when queried. var lastAccess = 0L @@ -69,14 +75,14 @@ class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends Abs @Callback(doc = """function([velocity:number]):boolean -- Eject the currently present medium from the drive.""") def eject(context: Context, args: Arguments): Array[AnyRef] = { val velocity = args.optDouble(0, 0) max 0 min 1 - val ejected = decrStackSize(0, 1) + val ejected = removeItem(0, 1) if (!ejected.isEmpty) { val entity = InventoryUtils.spawnStackInWorld(BlockPosition(rack), ejected, Option(rack.facing)) if (entity != null) { - val vx = rack.facing.getFrontOffsetX * velocity - val vy = rack.facing.getFrontOffsetY * velocity - val vz = rack.facing.getFrontOffsetZ * velocity - entity.addVelocity(vx, vy, vz) + val vx = rack.facing.getStepX * velocity + val vy = rack.facing.getStepY * velocity + val vz = rack.facing.getStepZ * velocity + entity.push(vx, vy, vz) } result(true) } @@ -86,7 +92,7 @@ class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends Abs // ----------------------------------------------------------------------- // // Analyzable - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = filesystemNode.fold(null: Array[Node])(Array(_)) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float): Array[Node] = filesystemNode.fold(null: Array[Node])(Array(_)) // ----------------------------------------------------------------------- // // ItemStackInventory @@ -96,19 +102,19 @@ class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends Abs // ----------------------------------------------------------------------- // // IInventory - override def getSizeInventory: Int = 1 + override def getContainerSize: Int = 1 - override def isItemValidForSlot(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack))) match { + override def canPlaceItem(slot: Int, stack: ItemStack): Boolean = (slot, Option(Driver.driverFor(stack))) match { case (0, Some(driver)) => driver.slot(stack) == Slot.Floppy case _ => false } - override def isUsableByPlayer(player: EntityPlayer): Boolean = rack.isUsableByPlayer(player) + override def stillValid(player: PlayerEntity): Boolean = rack.stillValid(player) // ----------------------------------------------------------------------- // // ComponentInventory - override def container: ItemStack = rack.getStackInSlot(slot) + override def container: ItemStack = rack.getItem(slot) override protected def onItemAdded(slot: Int, stack: ItemStack) { super.onItemAdded(slot, stack) @@ -118,7 +124,7 @@ class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends Abs } case _ => } - if (!rack.world.isRemote) { + if (!rack.world.isClientSide) { rack.markChanged(this.slot) Sound.playDiskInsert(rack) } @@ -126,7 +132,7 @@ class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends Abs override protected def onItemRemoved(slot: Int, stack: ItemStack) { super.onItemRemoved(slot, stack) - if (!rack.world.isRemote) { + if (!rack.world.isClientSide) { rack.markChanged(this.slot) Sound.playDiskEject(rack) } @@ -140,24 +146,24 @@ class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends Abs // ----------------------------------------------------------------------- // // Persistable - override def load(nbt: NBTTagCompound) { - super[AbstractManagedEnvironment].load(nbt) - super[ComponentInventory].load(nbt) + override def loadData(nbt: CompoundNBT) { + super[AbstractManagedEnvironment].loadData(nbt) + super[ComponentInventory].loadData(nbt) connectComponents() } - override def save(nbt: NBTTagCompound) { - super[AbstractManagedEnvironment].save(nbt) - super[ComponentInventory].save(nbt) + override def saveData(nbt: CompoundNBT) { + super[AbstractManagedEnvironment].saveData(nbt) + super[ComponentInventory].saveData(nbt) } // ----------------------------------------------------------------------- // // RackMountable - override def getData: NBTTagCompound = { - val nbt = new NBTTagCompound() - nbt.setLong("lastAccess", lastAccess) - nbt.setTag("disk", toNbt(getStackInSlot(0))) + override def getData: CompoundNBT = { + val nbt = new CompoundNBT() + nbt.putLong("lastAccess", lastAccess) + nbt.put("disk", toNbt(getItem(0))) nbt } @@ -165,28 +171,38 @@ class DiskDriveMountable(val rack: api.internal.Rack, val slot: Int) extends Abs override def getConnectableAt(index: Int): RackBusConnectable = null - override def onActivate(player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, hitX: Float, hitY: Float): Boolean = { - if (player.isSneaking) { - val isDiskInDrive = !getStackInSlot(0).isEmpty - val isHoldingDisk = isItemValidForSlot(0, heldItem) + override def onActivate(player: PlayerEntity, hand: Hand, heldItem: ItemStack, hitX: Float, hitY: Float): Boolean = { + if (player.isCrouching) { + val isDiskInDrive = !getItem(0).isEmpty + val isHoldingDisk = canPlaceItem(0, heldItem) if (isDiskInDrive) { - if (!rack.world.isRemote) { + if (!rack.world.isClientSide) { InventoryUtils.dropSlot(BlockPosition(rack), this, 0, 1, Option(rack.facing)) } } if (isHoldingDisk) { // Insert the disk. - setInventorySlotContents(0, player.inventory.decrStackSize(player.inventory.currentItem, 1)) + setItem(0, player.inventory.removeItem(player.inventory.selected, 1)) } isDiskInDrive || isHoldingDisk } - else { - val position = BlockPosition(rack) - player.openGui(OpenComputers, GuiType.DiskDriveMountableInRack.id, rack.world, position.x, GuiType.embedSlot(position.y, slot), position.z) - true + else player match { + case srvPlr: ServerPlayerEntity => { + srvPlr.openMenu(this) + true + } + case _ => false } } + // ----------------------------------------------------------------------- // + // INamedContainerProvider + + override def getDisplayName = StringTextComponent.EMPTY + + override def createMenu(id: Int, playerInventory: PlayerInventory, player: PlayerEntity) = + new DiskDriveContainer(ContainerTypes.DISK_DRIVE, id, playerInventory, this) + // ----------------------------------------------------------------------- // // StateAware diff --git a/src/main/scala/li/cil/oc/server/component/Drive.scala b/src/main/scala/li/cil/oc/server/component/Drive.scala index b62bb350be..0c64f54194 100644 --- a/src/main/scala/li/cil/oc/server/component/Drive.scala +++ b/src/main/scala/li/cil/oc/server/component/Drive.scala @@ -24,10 +24,11 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.server.{PacketSender => ServerPacketSender} -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.common.DimensionManager +import net.minecraft.nbt.CompoundNBT +import net.minecraft.world.storage.FolderName +import net.minecraftforge.fml.server.ServerLifecycleHooks -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Option[EnvironmentHost], val sound: Option[String], val speed: Int, val isLocked: Boolean) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -35,7 +36,7 @@ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Op withConnector(). create() - private def savePath = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + node.address + ".bin") + private def savePath = ServerLifecycleHooks.getCurrentServer.getWorldPath(new FolderName(Settings.savePath + node.address + ".bin")).toFile private final val sectorSize = 512 @@ -137,8 +138,8 @@ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Op private final val HeadPosTag = "headPos" - override def load(nbt: NBTTagCompound) = this.synchronized { - super.load(nbt) + override def loadData(nbt: CompoundNBT): Unit = this.synchronized { + super.loadData(nbt) if (node.address != null) try { val path = savePath @@ -157,15 +158,15 @@ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Op case t: Throwable => OpenComputers.log.warn(s"Failed loading drive contents for '${node.address}'.", t) } - headPos = nbt.getInteger(HeadPosTag) max 0 min sectorToHeadPos(sectorCount) + headPos = nbt.getInt(HeadPosTag) max 0 min sectorToHeadPos(sectorCount) if (label != null) { - label.load(nbt) + label.loadData(nbt) } } - override def save(nbt: NBTTagCompound) = this.synchronized { - super.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = this.synchronized { + super.saveData(nbt) if (node.address != null) try { val path = savePath @@ -180,10 +181,10 @@ class Drive(val capacity: Int, val platterCount: Int, val label: Label, host: Op case t: Throwable => OpenComputers.log.warn(s"Failed saving drive contents for '${node.address}'.", t) } - nbt.setInteger(HeadPosTag, headPos) + nbt.putInt(HeadPosTag, headPos) if (label != null) { - label.save(nbt) + label.saveData(nbt) } } diff --git a/src/main/scala/li/cil/oc/server/component/Drone.scala b/src/main/scala/li/cil/oc/server/component/Drone.scala index 359a2f7f0b..c97f6ec589 100644 --- a/src/main/scala/li/cil/oc/server/component/Drone.scala +++ b/src/main/scala/li/cil/oc/server/component/Drone.scala @@ -17,13 +17,13 @@ import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.common.entity import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.InventoryUtils -import net.minecraft.entity.item.EntityItem -import net.minecraft.init.SoundEvents -import net.minecraft.util.EnumFacing +import net.minecraft.entity.item.ItemEntity +import net.minecraft.util.SoundEvents +import net.minecraft.util.Direction import net.minecraft.util.SoundCategory -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ class Drone(val agent: entity.Drone) extends AbstractManagedEnvironment with Agent with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -44,11 +44,11 @@ class Drone(val agent: entity.Drone) extends AbstractManagedEnvironment with Age override protected def checkSideForAction(args: Arguments, n: Int) = args.checkSideAny(n) - override protected def suckableItems(side: EnumFacing) = entitiesInBlock(classOf[EntityItem], position) ++ super.suckableItems(side) + override protected def suckableItems(side: Direction) = entitiesInBlock(classOf[ItemEntity], position) ++ super.suckableItems(side) - override protected def onSuckCollect(entity: EntityItem) = { + override protected def onSuckCollect(entity: ItemEntity) = { if (InventoryUtils.insertIntoInventory(entity.getItem, InventoryUtils.asItemHandler(inventory), slots = Option(insertionSlots))) { - world.playSound(agent.player, agent.posX, agent.posY, agent.posZ, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.NEUTRAL, 0.2f, ((world.rand.nextFloat - world.rand.nextFloat) * 0.7f + 1) * 2) + world.playSound(agent.player, agent.getX, agent.getY, agent.getZ, SoundEvents.ITEM_PICKUP, SoundCategory.NEUTRAL, 0.2f, ((world.random.nextFloat - world.random.nextFloat) * 0.7f + 1) * 2) } } @@ -93,14 +93,14 @@ class Drone(val agent: entity.Drone) extends AbstractManagedEnvironment with Age @Callback(doc = "function():number -- Get the current distance to the target position.") def getOffset(context: Context, args: Arguments): Array[AnyRef] = - result(agent.getDistance(agent.targetX.floatValue(), agent.targetY.floatValue(), agent.targetZ.floatValue())) + result(agent.position.distanceTo(agent.getTarget())) @Callback(doc = "function():number -- Get the current velocity in m/s.") def getVelocity(context: Context, args: Arguments): Array[AnyRef] = - result(math.sqrt(agent.motionX * agent.motionX + agent.motionY * agent.motionY + agent.motionZ * agent.motionZ) * 20) // per second + result(agent.getDeltaMovement.length * 20) // per second @Callback(doc = "function():number -- Get the maximum velocity, in m/s.") - def getMaxVelocity(context: Context, args: Arguments): Array[AnyRef] = { + def getV1elocity(context: Context, args: Arguments): Array[AnyRef] = { result(agent.maxVelocity * 20) // per second } diff --git a/src/main/scala/li/cil/oc/server/component/EEPROM.scala b/src/main/scala/li/cil/oc/server/component/EEPROM.scala index 1367527e6b..2c1ab3c07c 100644 --- a/src/main/scala/li/cil/oc/server/component/EEPROM.scala +++ b/src/main/scala/li/cil/oc/server/component/EEPROM.scala @@ -15,9 +15,9 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.network._ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class EEPROM extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Neighbors). @@ -56,10 +56,10 @@ class EEPROM extends AbstractManagedEnvironment with DeviceInfo { @Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""") def set(context: Context, args: Arguments): Array[AnyRef] = { if (readonly) { - return result(Unit, "storage is readonly") + return result((), "storage is readonly") } if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) { - return result(Unit, "not enough energy") + return result((), "not enough energy") } val newData = args.optByteArray(0, Array.empty[Byte]) if (newData.length > Settings.get.eepromSize) throw new IllegalArgumentException("not enough space") @@ -74,7 +74,7 @@ class EEPROM extends AbstractManagedEnvironment with DeviceInfo { @Callback(doc = """function(data:string):string -- Set the label of the EEPROM.""") def setLabel(context: Context, args: Arguments): Array[AnyRef] = { if (readonly) { - return result(Unit, "storage is readonly") + return result((), "storage is readonly") } label = args.optString(0, "EEPROM").trim.take(24) if (label.length == 0) label = "EEPROM" @@ -93,7 +93,7 @@ class EEPROM extends AbstractManagedEnvironment with DeviceInfo { readonly = true result(true) } - else result(Unit, "incorrect checksum") + else result((), "incorrect checksum") } @Callback(direct = true, doc = """function():number -- Get the storage capacity of this EEPROM.""") @@ -105,7 +105,7 @@ class EEPROM extends AbstractManagedEnvironment with DeviceInfo { @Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""") def setData(context: Context, args: Arguments): Array[AnyRef] = { if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) { - return result(Unit, "not enough energy") + return result((), "not enough energy") } val newData = args.optByteArray(0, Array.empty[Byte]) if (newData.length > Settings.get.eepromDataSize) throw new IllegalArgumentException("not enough space") @@ -121,21 +121,21 @@ class EEPROM extends AbstractManagedEnvironment with DeviceInfo { private final val ReadonlyTag = Settings.namespace + "readonly" private final val UserdataTag = Settings.namespace + "userdata" - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) codeData = nbt.getByteArray(EEPROMTag) - if (nbt.hasKey(LabelTag)) { + if (nbt.contains(LabelTag)) { label = nbt.getString(LabelTag) } readonly = nbt.getBoolean(ReadonlyTag) volatileData = nbt.getByteArray(UserdataTag) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setByteArray(EEPROMTag, codeData) - nbt.setString(LabelTag, label) - nbt.setBoolean(ReadonlyTag, readonly) - nbt.setByteArray(UserdataTag, volatileData) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putByteArray(EEPROMTag, codeData) + nbt.putString(LabelTag, label) + nbt.putBoolean(ReadonlyTag, readonly) + nbt.putByteArray(UserdataTag, volatileData) } } diff --git a/src/main/scala/li/cil/oc/server/component/FileSystem.scala b/src/main/scala/li/cil/oc/server/component/FileSystem.scala index c496625a9a..2d83b36405 100644 --- a/src/main/scala/li/cil/oc/server/component/FileSystem.scala +++ b/src/main/scala/li/cil/oc/server/component/FileSystem.scala @@ -24,12 +24,12 @@ import li.cil.oc.api.prefab.AbstractValue import li.cil.oc.common.SaveHandler import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagIntArray -import net.minecraft.nbt.NBTTagList +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.IntArrayNBT +import net.minecraft.nbt.ListNBT import net.minecraftforge.common.util.Constants.NBT -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option[EnvironmentHost], val sound: Option[String], val speed: Int) extends AbstractManagedEnvironment with DeviceInfo { @@ -197,7 +197,7 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option result(bytes) } else { - result(Unit) + result(()) } case _ => throw new IOException("bad file descriptor") } @@ -303,40 +303,40 @@ class FileSystem(val fileSystem: IFileSystem, var label: Label, val host: Option // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) - nbt.getTagList("owners", NBT.TAG_COMPOUND).foreach((ownerNbt: NBTTagCompound) => { + nbt.getList("owners", NBT.TAG_COMPOUND).foreach((ownerNbt: CompoundNBT) => { val address = ownerNbt.getString("address") if (address != "") { - owners += address -> ownerNbt.getIntArray("handles").to[mutable.Set] + owners += address -> ownerNbt.getIntArray("handles").to(mutable.Set) } }) if (label != null) { - label.load(nbt) + label.loadData(nbt) } - fileSystem.load(nbt.getCompoundTag("fs")) + fileSystem.loadData(nbt.getCompound("fs")) } - override def save(nbt: NBTTagCompound) = fileSystem.synchronized { - super.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = fileSystem.synchronized { + super.saveData(nbt) if (label != null) { - label.save(nbt) + label.saveData(nbt) } if (!SaveHandler.savingForClients) { - val ownersNbt = new NBTTagList() + val ownersNbt = new ListNBT() for ((address, handles) <- owners) { - val ownerNbt = new NBTTagCompound() - ownerNbt.setString("address", address) - ownerNbt.setTag("handles", new NBTTagIntArray(handles.toArray)) - ownersNbt.appendTag(ownerNbt) + val ownerNbt = new CompoundNBT() + ownerNbt.putString("address", address) + ownerNbt.put("handles", new IntArrayNBT(handles.toArray)) + ownersNbt.add(ownerNbt) } - nbt.setTag("owners", ownersNbt) + nbt.put("owners", ownersNbt) - nbt.setNewCompoundTag("fs", fileSystem.save) + nbt.setNewCompoundTag("fs", fileSystem.saveData) } } @@ -395,16 +395,16 @@ final class HandleValue extends AbstractValue { private val OwnerTag = "owner" private val HandleTag = "handle" - override def load(nbt: NBTTagCompound): Unit = { - super.load(nbt) + override def loadData(nbt: CompoundNBT): Unit = { + super.loadData(nbt) owner = nbt.getString(OwnerTag) - handle = nbt.getInteger(HandleTag) + handle = nbt.getInt(HandleTag) } - override def save(nbt: NBTTagCompound): Unit = { - super.save(nbt) - nbt.setString(OwnerTag, owner) - nbt.setInteger(HandleTag, handle) + override def saveData(nbt: CompoundNBT): Unit = { + super.saveData(nbt) + nbt.putString(OwnerTag, owner) + nbt.putInt(HandleTag, handle) } override def toString: String = handle.toString diff --git a/src/main/scala/li/cil/oc/server/component/Geolyzer.scala b/src/main/scala/li/cil/oc/server/component/Geolyzer.scala index c6495ae4f8..a6c44b80ef 100644 --- a/src/main/scala/li/cil/oc/server/component/Geolyzer.scala +++ b/src/main/scala/li/cil/oc/server/component/Geolyzer.scala @@ -26,15 +26,20 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.DatabaseAccess import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.Block +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraft.world.World +import net.minecraft.world.biome.Biome.RainType +import net.minecraft.world.server.ServerWorld import net.minecraftforge.common.MinecraftForge -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.mapAsJavaMap +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.language.existentials class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment with traits.WorldControl with DeviceInfo { @@ -55,7 +60,7 @@ class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment wit // ----------------------------------------------------------------------- // - override protected def checkSideForAction(args: Arguments, n: Int): EnumFacing = { + override protected def checkSideForAction(args: Arguments, n: Int): Direction = { val side = args.checkSideAny(n) val is_uc = host.isInstanceOf[Microcontroller] host match { @@ -69,15 +74,15 @@ class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment wit override def position: BlockPosition = host match { case robot: EntityRobot => robot.proxy.position - case drone: EntityDrone => BlockPosition(drone.getPosition, drone.getEntityWorld) + case drone: EntityDrone => BlockPosition(drone.blockPosition, drone.level) case uc: Microcontroller => uc.position case tablet: TabletWrapper => BlockPosition(tablet.xPosition, tablet.yPosition, tablet.zPosition, tablet.world) case _ => BlockPosition(host) } private def canSeeSky: Boolean = { - val blockPos = position.offset(EnumFacing.UP) - !host.world.provider.isNether && host.world.canBlockSeeSky(blockPos.toBlockPos) + val blockPos = position.offset(Direction.UP) + host.world.dimension != World.NETHER && host.world.canSeeSkyFromBelowWater(blockPos.toBlockPos) } @Callback(doc = """function():boolean -- Returns whether there is a clear line of sight to the sky directly above.""") @@ -87,11 +92,11 @@ class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment wit @Callback(doc = """function():boolean -- Return whether the sun is currently visible directly above.""") def isSunVisible(computer: Context, args: Arguments): Array[AnyRef] = { - val blockPos = BlockPosition(host).offset(EnumFacing.UP) + val blockPos = BlockPosition(host).offset(Direction.UP) result( - host.world.isDaytime && + host.world.isDay && canSeeSky && - (!host.world.getBiome(blockPos.toBlockPos).canRain || (!host.world.isRaining && !host.world.isThundering))) + (host.world.getBiome(blockPos.toBlockPos).getPrecipitation == RainType.NONE || (!host.world.isRaining && !host.world.isThundering))) } @Callback(doc = """function(x:number, z:number[, y:number, w:number, d:number, h:number][, ignoreReplaceable:boolean|options:table]):table -- Analyzes the density of the column at the specified relative coordinates.""") @@ -107,11 +112,11 @@ class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment wit } if (!node.tryChangeBuffer(-Settings.get.geolyzerScanCost)) - return result(Unit, "not enough energy") + return result((), "not enough energy") val event = new GeolyzerEvent.Scan(host, options, minX, minY, minZ, maxX, maxY, maxZ) MinecraftForge.EVENT_BUS.post(event) - if (event.isCanceled) result(Unit, "scan was canceled") + if (event.isCanceled) result((), "scan was canceled") else result(event.data) } @@ -146,15 +151,15 @@ class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment wit val options = args.optTable(1, Map.empty[AnyRef, AnyRef]) if (!node.tryChangeBuffer(-Settings.get.geolyzerScanCost)) - return result(Unit, "not enough energy") + return result((), "not enough energy") val globalPos = BlockPosition(host).offset(globalSide) val event = new Analyze(host, options, globalPos.toBlockPos) MinecraftForge.EVENT_BUS.post(event) - if (event.isCanceled) result(Unit, "scan was canceled") + if (event.isCanceled) result((), "scan was canceled") else result(event.data) } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") @Callback(doc = """function(side:number, dbAddress:string, dbSlot:number):boolean -- Store an item stack representation of the block on the specified side in a database component.""") def store(computer: Context, args: Arguments): Array[AnyRef] = { @@ -165,16 +170,20 @@ class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment wit } if (!node.tryChangeBuffer(-Settings.get.geolyzerScanCost)) - return result(Unit, "not enough energy") + return result((), "not enough energy") val blockPos = BlockPosition(host).offset(globalSide) - val block = host.world.getBlock(blockPos) - val item = Item.getItemFromBlock(block) - if (item == null) result(Unit, "block has no registered item representation") + val blockState = host.world.getBlockState(blockPos.toBlockPos) + val item = blockState.getBlock().asItem() + if (item == null) result((), "block has no registered item representation") else { - val metadata = host.world.getBlockMetadata(blockPos) - val damage = block.damageDropped(metadata) - val stack = new ItemStack(item, 1, damage) + val stacks = Block.getDrops(blockState, host.world.asInstanceOf[ServerWorld], blockPos.toBlockPos, host.world.getBlockEntity(blockPos.toBlockPos)) + val stack = if (!stacks.isEmpty) { + val drop = stacks.find(s => s.getItem == item).getOrElse(stacks.get(0)) + drop.setCount(1) + drop + } + else new ItemStack(item, 1) DatabaseAccess.withDatabase(node, args.checkString(1), database => { val toSlot = args.checkSlot(database.data, 2) val nonEmpty = database.getStackInSlot(toSlot) != ItemStack.EMPTY // not the same as isEmpty! zero size stacks! @@ -188,14 +197,14 @@ class Geolyzer(val host: EnvironmentHost) extends AbstractManagedEnvironment wit super.onMessage(message) if (message.name == "tablet.use") message.source.host match { case machine: api.machine.Machine => (machine.host, message.data) match { - case (tablet: internal.Tablet, Array(nbt: NBTTagCompound, stack: ItemStack, player: EntityPlayer, blockPos: BlockPosition, side: EnumFacing, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => + case (tablet: internal.Tablet, Array(nbt: CompoundNBT, stack: ItemStack, player: PlayerEntity, blockPos: BlockPosition, side: Direction, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => if (node.tryChangeBuffer(-Settings.get.geolyzerScanCost)) { val event = new Analyze(host, Map.empty[AnyRef, AnyRef], blockPos.toBlockPos) MinecraftForge.EVENT_BUS.post(event) if (!event.isCanceled) { for ((key, value) <- event.data) value match { - case number: java.lang.Number => nbt.setDouble(key, number.doubleValue()) - case string: String if !string.isEmpty => nbt.setString(key, string) + case number: java.lang.Number => nbt.putDouble(key, number.doubleValue()) + case string: String if !string.isEmpty => nbt.putString(key, string) case _ => // Unsupported, ignore. } } diff --git a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala index cac1beed12..37a1382d65 100644 --- a/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala +++ b/src/main/scala/li/cil/oc/server/component/GraphicsCard.scala @@ -12,11 +12,11 @@ import li.cil.oc.api.network._ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.PackedColor -import net.minecraft.nbt.{NBTTagCompound, NBTTagList} +import net.minecraft.nbt.{CompoundNBT, ListNBT} import li.cil.oc.common.component import li.cil.oc.common.component.GpuTextBuffer -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.util.matching.Regex // IMPORTANT: usually methods with side effects should *not* be direct @@ -51,12 +51,12 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device if (index == RESERVED_SCREEN_INDEX) { screenInstance match { case Some(screen) => screen.synchronized(f(screen)) - case _ => Array(Unit, "no screen") + case _ => Array(null, "no screen") } } else { getBuffer(index) match { case Some(buffer: api.internal.TextBuffer) => f(buffer) - case _ => Array(Unit, "invalid buffer index") + case _ => Array(null, "invalid buffer index") } } } @@ -118,7 +118,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device val previousIndex: Int = bufferIndex val newIndex: Int = args.checkInteger(0) if (newIndex != RESERVED_SCREEN_INDEX && getBuffer(newIndex).isEmpty) { - result(Unit, "invalid buffer index") + result((), "invalid buffer index") } else { bufferIndex = newIndex if (bufferIndex == RESERVED_SCREEN_INDEX) { @@ -139,12 +139,12 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device val height: Int = args.optInteger(1, maxResolution._2) val size: Int = width * height if (width <= 0 || height <= 0) { - result(Unit, "invalid page dimensions: must be greater than zero") + result((), "invalid page dimensions: must be greater than zero") } else if (size > (totalVRAM - calculateUsedMemory)) { - result(Unit, "not enough video memory") + result((), "not enough video memory") } else if (node == null) { - result(Unit, "graphics card appears disconnected") + result((), "graphics card appears disconnected") } else { val format: PackedColor.ColorFormat = PackedColor.Depth.format(Settings.screenDepthsByTier(tier)) val buffer = new li.cil.oc.util.TextBuffer(width, height, format) @@ -173,7 +173,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device def freeBuffer(context: Context, args: Arguments): Array[AnyRef] = { val index: Int = args.optInteger(0, bufferIndex) if (removeBuffers(Array(index)) == 1) result(true) - else result(Unit, "no buffer at index") + else result((), "no buffer at index") } @Callback(direct = true, doc = """function(): number -- Closes all buffers and returns the count. If the active buffer is closed, index moves to 0""") @@ -263,7 +263,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device component.GpuTextBuffer.bitblt(dst, col, row, w, h, src, fromRow, fromCol) result(true) } - } else result(Unit, "not enough energy") + } else result((), "not enough energy") }) }) } @@ -273,7 +273,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device val address = args.checkString(0) val reset = args.optBoolean(1, true) node.network.node(address) match { - case null => result(Unit, "invalid address") + case null => result((), "invalid address") case node: Node if node.host.isInstanceOf[api.internal.TextBuffer] => screenAddress = Option(address) screenInstance = Some(node.host.asInstanceOf[api.internal.TextBuffer]) @@ -294,7 +294,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device else context.pause(0) // To discourage outputting "in realtime" to multiple screens using one GPU. result(true) }) - case _ => result(Unit, "not a screen") + case _ => result((), "not a screen") } } @@ -318,7 +318,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device (s.getPaletteColor(oldValue), oldValue) } else { - (oldValue, Unit) + (oldValue, ()) } s.setBackgroundColor(color, args.optBoolean(1, false)) result(oldColor, oldIndex) @@ -342,7 +342,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device (s.getPaletteColor(oldValue), oldValue) } else { - (oldValue, Unit) + (oldValue, ()) } s.setForegroundColor(color, args.optBoolean(1, false)) result(oldColor, oldIndex) @@ -449,8 +449,8 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device // if (bufferIndex != RESERVED_SCREEN_INDEX && args.count() == 0) { // return screen { // case ram: GpuTextBuffer => { -// val nbt = new NBTTagCompound -// ram.data.save(nbt) +// val nbt = new CompoundNBT +// ram.data.saveData(nbt) // result(nbt) // } // } @@ -464,7 +464,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device (s.getPaletteColor(fgValue), fgValue) } else { - (fgValue, Unit) + (fgValue, ()) } val bgValue = s.getBackgroundColor(x, y) @@ -473,7 +473,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device (s.getPaletteColor(bgValue), bgValue) } else { - (bgValue, Unit) + (bgValue, ()) } result(s.get(x, y), fgColor, bgColor, fgIndex, bgIndex) @@ -491,7 +491,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device if (resolveInvokeCosts(bufferIndex, context, setCosts(tier), value.length, Settings.get.gpuSetCost)) { s.set(x, y, value, vertical) result(true) - } else result(Unit, "not enough energy") + } else result((), "not enough energy") }) } @@ -508,7 +508,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device s.copy(x, y, w, h, tx, ty) result(true) } - else result(Unit, "not enough energy") + else result((), "not enough energy") }) } @@ -527,7 +527,7 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device result(true) } else { - result(Unit, "not enough energy") + result((), "not enough energy") } }) else throw new Exception("invalid fill value") @@ -615,12 +615,12 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device private final val NBT_PAGES: String = "pages" private final val NBT_PAGE_IDX: String = "page_idx" private final val NBT_PAGE_DATA: String = "page_data" - private val COMPOUND_ID = (new NBTTagCompound).getId + private val COMPOUND_ID = (new CompoundNBT).getId - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) - if (nbt.hasKey(SCREEN_KEY)) { + if (nbt.contains(SCREEN_KEY)) { nbt.getString(SCREEN_KEY) match { case screen: String if !screen.isEmpty => screenAddress = Some(screen) case _ => screenAddress = None @@ -628,50 +628,50 @@ class GraphicsCard(val tier: Int) extends AbstractManagedEnvironment with Device screenInstance = None } - if (nbt.hasKey(BUFFER_INDEX_KEY)) { - bufferIndex = nbt.getInteger(BUFFER_INDEX_KEY) + if (nbt.contains(BUFFER_INDEX_KEY)) { + bufferIndex = nbt.getInt(BUFFER_INDEX_KEY) } removeAllBuffers() // JUST in case - if (nbt.hasKey(VIDEO_RAM_KEY)) { - val videoRamNbt = nbt.getCompoundTag(VIDEO_RAM_KEY) - val nbtPages = videoRamNbt.getTagList(NBT_PAGES, COMPOUND_ID) - for (i <- 0 until nbtPages.tagCount) { - val nbtPage = nbtPages.getCompoundTagAt(i) - val idx: Int = nbtPage.getInteger(NBT_PAGE_IDX) - val data = nbtPage.getCompoundTag(NBT_PAGE_DATA) + if (nbt.contains(VIDEO_RAM_KEY)) { + val videoRamNbt = nbt.getCompound(VIDEO_RAM_KEY) + val nbtPages = videoRamNbt.getList(NBT_PAGES, COMPOUND_ID) + for (i <- 0 until nbtPages.size) { + val nbtPage = nbtPages.getCompound(i) + val idx: Int = nbtPage.getInt(NBT_PAGE_IDX) + val data = nbtPage.getCompound(NBT_PAGE_DATA) loadBuffer(node.address, idx, data) } } } - override def save(nbt: NBTTagCompound) { - super.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) if (screenAddress.isDefined) { - nbt.setString(SCREEN_KEY, screenAddress.get) + nbt.putString(SCREEN_KEY, screenAddress.get) } - nbt.setInteger(BUFFER_INDEX_KEY, bufferIndex) + nbt.putInt(BUFFER_INDEX_KEY, bufferIndex) - val videoRamNbt = new NBTTagCompound - val nbtPages = new NBTTagList + val videoRamNbt = new CompoundNBT + val nbtPages = new ListNBT val indexes = bufferIndexes() for (idx: Int <- indexes) { getBuffer(idx) match { case Some(page) => { - val nbtPage = new NBTTagCompound - nbtPage.setInteger(NBT_PAGE_IDX, idx) - val data = new NBTTagCompound - page.data.save(data) - nbtPage.setTag(NBT_PAGE_DATA, data) - nbtPages.appendTag(nbtPage) + val nbtPage = new CompoundNBT + nbtPage.putInt(NBT_PAGE_IDX, idx) + val data = new CompoundNBT + page.data.saveData(data) + nbtPage.put(NBT_PAGE_DATA, data) + nbtPages.add(nbtPage) } case _ => // ignore } } - videoRamNbt.setTag(NBT_PAGES, nbtPages) - nbt.setTag(VIDEO_RAM_KEY, videoRamNbt) + videoRamNbt.put(NBT_PAGES, nbtPages) + nbt.put(VIDEO_RAM_KEY, videoRamNbt) } } diff --git a/src/main/scala/li/cil/oc/server/component/InternetCard.scala b/src/main/scala/li/cil/oc/server/component/InternetCard.scala index e4c4df868a..6f3e3aa75c 100644 --- a/src/main/scala/li/cil/oc/server/component/InternetCard.scala +++ b/src/main/scala/li/cil/oc/server/component/InternetCard.scala @@ -32,10 +32,10 @@ import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.api.prefab.AbstractValue import li.cil.oc.util.ThreadPoolFactory import net.minecraft.server.MinecraftServer -import net.minecraftforge.fml.common.FMLCommonHandler +import net.minecraftforge.fml.server.ServerLifecycleHooks -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class InternetCard extends AbstractManagedEnvironment with DeviceInfo { @@ -68,7 +68,7 @@ class InternetCard extends AbstractManagedEnvironment with DeviceInfo { checkOwner(context) val address = args.checkString(0) if (!Settings.get.httpEnabled) { - return result(Unit, "http requests are unavailable") + return result((), "http requests are unavailable") } if (connections.size >= Settings.get.maxConnections) { throw new IOException("too many open connections") @@ -79,7 +79,7 @@ class InternetCard extends AbstractManagedEnvironment with DeviceInfo { }.toMap else Map.empty[String, String] if (!Settings.get.httpHeadersEnabled && headers.nonEmpty) { - return result(Unit, "http request headers are unavailable") + return result((), "http request headers are unavailable") } val method = if (args.isString(3)) Option(args.checkString(3)) else None val request = new InternetCard.HTTPRequest(this, checkAddress(address), post, headers, method) @@ -96,7 +96,7 @@ class InternetCard extends AbstractManagedEnvironment with DeviceInfo { val address = args.checkString(0) val port = args.optInteger(1, -1) if (!Settings.get.tcpEnabled) { - return result(Unit, "tcp connections are unavailable") + return result((), "tcp connections are unavailable") } if (connections.size >= Settings.get.maxConnections) { throw new IOException("too many open connections") @@ -203,7 +203,6 @@ object InternetCard { selector.select() - import scala.collection.JavaConversions._ val selectedKeys = selector.selectedKeys val readableKeys = mutable.HashSet[SelectionKey]() selectedKeys.filter(_.isReadable).foreach(key => { @@ -274,10 +273,10 @@ object InternetCard { if (checkConnected()) { val buffer = ByteBuffer.allocate(n) val read = channel.read(buffer) - if (read == -1) result(Unit) + if (read == -1) result(()) else { setupSelector() - result(buffer.array.view(0, read).toArray) + result(buffer.array.view.slice(0, read).toArray) } } else result(Array.empty[Byte]) @@ -389,7 +388,7 @@ object InternetCard { def response(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { response match { case Some((code, message, headers)) => result(code, message, headers) - case _ => result(Unit) + case _ => result(()) } } @@ -397,7 +396,7 @@ object InternetCard { def read(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { val n = math.min(Settings.get.maxReadBuffer, math.max(0, args.optInteger(0, Int.MaxValue))) if (checkResponse()) { - if (eof && queue.isEmpty) result(Unit) + if (eof && queue.isEmpty) result(()) else { val buffer = ByteBuffer.allocate(n) var read = 0 @@ -408,7 +407,7 @@ object InternetCard { if (read == 0) { readMore() } - result(buffer.array.view(0, read).toArray) + result(buffer.array.view.slice(0, read).toArray) } } else result(Array.empty[Byte]) @@ -474,7 +473,7 @@ object InternetCard { private class RequestSender(val url: URL, val post: Option[String], val headers: Map[String, String], val method: Option[String]) extends Callable[InputStream] { override def call() = try { checkLists(InetAddress.getByName(url.getHost), url.getHost) - val proxy = Option(FMLCommonHandler.instance.getMinecraftServerInstance.getServerProxy).getOrElse(java.net.Proxy.NO_PROXY) + val proxy = java.net.Proxy.NO_PROXY url.openConnection(proxy) match { case http: HttpURLConnection => try { http.setDoInput(true) diff --git a/src/main/scala/li/cil/oc/server/component/Keyboard.scala b/src/main/scala/li/cil/oc/server/component/Keyboard.scala index 78c6a8a425..a825508711 100644 --- a/src/main/scala/li/cil/oc/server/component/Keyboard.scala +++ b/src/main/scala/li/cil/oc/server/component/Keyboard.scala @@ -15,9 +15,9 @@ import li.cil.oc.api.network.Message import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable // TODO key up when screen is disconnected from which the key down came @@ -28,7 +28,7 @@ class Keyboard(val host: EnvironmentHost) extends AbstractManagedEnvironment wit withComponent("keyboard"). create() - val pressedKeys = mutable.Map.empty[EntityPlayer, mutable.Map[Integer, Character]] + val pressedKeys = mutable.Map.empty[PlayerEntity, mutable.Map[Integer, Character]] var usableOverride: Option[api.internal.Keyboard.UsabilityChecker] = None @@ -47,11 +47,11 @@ class Keyboard(val host: EnvironmentHost) extends AbstractManagedEnvironment wit // ----------------------------------------------------------------------- // - def releasePressedKeys(player: EntityPlayer) { + def releasePressedKeys(player: PlayerEntity) { pressedKeys.get(player) match { case Some(keys) => for ((code, char) <- keys) { if (Settings.get.inputUsername) { - signal(player, "key_up", char, code, player.getName) + signal(player, "key_up", char, code, player.getName.getString) } else { signal(player, "key_up", char, code) @@ -66,33 +66,40 @@ class Keyboard(val host: EnvironmentHost) extends AbstractManagedEnvironment wit override def onMessage(message: Message) = { message.data match { - case Array(p: EntityPlayer, char: Character, code: Integer) if message.name == "keyboard.keyDown" => + case Array(p: PlayerEntity, char: Character, code: Integer) if message.name == "keyboard.keyDown" => if (isUsableByPlayer(p)) { pressedKeys.getOrElseUpdate(p, mutable.Map.empty[Integer, Character]) += code -> char if (Settings.get.inputUsername) { - signal(p, "key_down", char, code, p.getName) + signal(p, "key_down", char, code, p.getName.getString) } else { signal(p, "key_down", char, code) } } - case Array(p: EntityPlayer, char: Character, code: Integer) if message.name == "keyboard.keyUp" => + case Array(p: PlayerEntity, char: Character, code: Integer) if message.name == "keyboard.keyUp" => pressedKeys.get(p) match { case Some(keys) if keys.contains(code) => keys -= code if (Settings.get.inputUsername) { - signal(p, "key_up", char, code, p.getName) + signal(p, "key_up", char, code, p.getName.getString) } else { signal(p, "key_up", char, code) } case _ => } - case Array(p: EntityPlayer, value: String) if message.name == "keyboard.clipboard" => + case Array(p: PlayerEntity, codePt: Integer) if message.name == "keyboard.textInput" => + if (Settings.get.inputUsername) { + signal(p, "text_input", new String(Character.toChars(codePt)), p.getName.getString) + } + else { + signal(p, "text_input", new String(Character.toChars(codePt))) + } + case Array(p: PlayerEntity, value: String) if message.name == "keyboard.clipboard" => if (isUsableByPlayer(p)) { for (line <- value.linesWithSeparators) { if (Settings.get.inputUsername) { - signal(p, "clipboard", line, p.getName) + signal(p, "clipboard", line, p.getName.getString) } else { signal(p, "clipboard", line) @@ -105,9 +112,9 @@ class Keyboard(val host: EnvironmentHost) extends AbstractManagedEnvironment wit // ----------------------------------------------------------------------- // - def isUsableByPlayer(p: EntityPlayer) = usableOverride match { + def isUsableByPlayer(p: PlayerEntity) = usableOverride match { case Some(callback) => callback.isUsableByPlayer(this, p) - case _ => p.getDistanceSq(host.xPosition, host.yPosition, host.zPosition) <= 64 + case _ => p.distanceToSqr(host.xPosition, host.yPosition, host.zPosition) <= 64 } protected def signal(args: AnyRef*) = diff --git a/src/main/scala/li/cil/oc/server/component/LinkedCard.scala b/src/main/scala/li/cil/oc/server/component/LinkedCard.scala index 564b5c321b..00bd5fe09d 100644 --- a/src/main/scala/li/cil/oc/server/component/LinkedCard.scala +++ b/src/main/scala/li/cil/oc/server/component/LinkedCard.scala @@ -16,10 +16,10 @@ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.common.Tier import li.cil.oc.server.network.QuantumNetwork -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ class LinkedCard extends AbstractManagedEnvironment with QuantumNetwork.QuantumNode with DeviceInfo with traits.WakeMessageAware { override val node = Network.newNode(this, Visibility.Network). @@ -55,7 +55,7 @@ class LinkedCard extends AbstractManagedEnvironment with QuantumNetwork.QuantumN } result(true) } - else result(Unit, "not enough energy") + else result((), "not enough energy") } @Callback(direct = true, doc = "function():number -- Gets the maximum packet size (config setting).") @@ -88,17 +88,17 @@ class LinkedCard extends AbstractManagedEnvironment with QuantumNetwork.QuantumN private final val TunnelTag = Settings.namespace + "tunnel" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - if (nbt.hasKey(TunnelTag)) { + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + if (nbt.contains(TunnelTag)) { tunnel = nbt.getString(TunnelTag) } loadWakeMessage(nbt) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setString(TunnelTag, tunnel) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putString(TunnelTag, tunnel) saveWakeMessage(nbt) } } diff --git a/src/main/scala/li/cil/oc/server/component/Memory.scala b/src/main/scala/li/cil/oc/server/component/Memory.scala index ae0b167131..545400e097 100644 --- a/src/main/scala/li/cil/oc/server/component/Memory.scala +++ b/src/main/scala/li/cil/oc/server/component/Memory.scala @@ -12,7 +12,7 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class Memory(val tier: Int) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Neighbors). diff --git a/src/main/scala/li/cil/oc/server/component/MotionSensor.scala b/src/main/scala/li/cil/oc/server/component/MotionSensor.scala index ac476b248c..fce5a745bc 100644 --- a/src/main/scala/li/cil/oc/server/component/MotionSensor.scala +++ b/src/main/scala/li/cil/oc/server/component/MotionSensor.scala @@ -15,13 +15,15 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.util.SideTracker -import net.minecraft.entity.EntityLivingBase -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.potion.Potion -import net.minecraft.util.math.{AxisAlignedBB, BlockPos, Vec3d} - -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import net.minecraft.entity.LivingEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.potion.Effect +import net.minecraft.potion.Effects +import net.minecraft.util.math.{AxisAlignedBB, BlockPos, RayTraceContext, RayTraceResult} +import net.minecraft.util.math.vector.Vector3d + +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class MotionSensor(val host: EnvironmentHost) extends prefab.AbstractManagedEnvironment with DeviceInfo { @@ -34,7 +36,7 @@ class MotionSensor(val host: EnvironmentHost) extends prefab.AbstractManagedEnvi private var sensitivity = 0.4 - private val trackedEntities = mutable.Map.empty[EntityLivingBase, (Double, Double, Double)] + private val trackedEntities = mutable.Map.empty[LivingEntity, (Double, Double, Double)] private final lazy val deviceInfo = Map( DeviceAttribute.Class -> DeviceClass.Generic, @@ -56,19 +58,19 @@ class MotionSensor(val host: EnvironmentHost) extends prefab.AbstractManagedEnvi private def z = host.zPosition - private def isServer: Boolean = if (world != null) !world.isRemote else SideTracker.isServer + private def isServer: Boolean = if (world != null) !world.isClientSide else SideTracker.isServer override def canUpdate: Boolean = isServer override def update() { super.update() - if (world.getTotalWorldTime % 10 == 0) { + if (world.getGameTime % 10 == 0) { // Get a list of all living entities we could possibly detect, using a rough // bounding box check, then refining it using the actual distance and an // actual visibility check. - val entities = world.getEntitiesWithinAABB(classOf[EntityLivingBase], sensorBounds) - .map(_.asInstanceOf[EntityLivingBase]) - .filter(entity => entity.isEntityAlive && isInRange(entity) && isVisible(entity)) + val entities = world.getEntitiesOfClass(classOf[LivingEntity], sensorBounds) + .map(_.asInstanceOf[LivingEntity]) + .filter(entity => entity.isAlive && isInRange(entity) && isVisible(entity)) .toSet // Get rid of all tracked entities that are no longer visible. trackedEntities.retain((key, _) => entities.contains(key)) @@ -77,7 +79,7 @@ class MotionSensor(val host: EnvironmentHost) extends prefab.AbstractManagedEnvi trackedEntities.get(entity) match { case Some((prevX, prevY, prevZ)) => // Known entity, check if it moved enough to trigger. - if (entity.getDistanceSq(prevX, prevY, prevZ) > sensitivity * sensitivity * 2) { + if (entity.distanceToSqr(prevX, prevY, prevZ) > sensitivity * sensitivity * 2) { sendSignal(entity) } case _ => @@ -85,7 +87,7 @@ class MotionSensor(val host: EnvironmentHost) extends prefab.AbstractManagedEnvi sendSignal(entity) } // Update tracked position. - trackedEntities += entity ->(entity.posX, entity.posY, entity.posZ) + trackedEntities += entity ->(entity.getX, entity.getY, entity.getZ) } } } @@ -94,31 +96,32 @@ class MotionSensor(val host: EnvironmentHost) extends prefab.AbstractManagedEnvi x + 0.5 - radius, y + 0.5 - radius, z + 0.5 - radius, x + 0.5 + radius, y + 0.5 + radius, z + 0.5 + radius) - private def isInRange(entity: EntityLivingBase) = entity.getDistanceSq(x + 0.5, y + 0.5, z + 0.5) <= radius * radius + private def isInRange(entity: LivingEntity) = entity.distanceToSqr(x + 0.5, y + 0.5, z + 0.5) <= radius * radius - private def isClearPath(target: Vec3d): Boolean = { - val origin = new Vec3d(x, y, z) + private def isClearPath(target: Vector3d): Boolean = { + val origin = new Vector3d(x, y, z) val path = target.subtract(origin).normalize() val eye = origin.add(path) - world.rayTraceBlocks(eye, target) == null + val trace = world.clip(new RayTraceContext(eye, target, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.ANY, null)) + trace.getType == RayTraceResult.Type.MISS } - private def isVisible(entity: EntityLivingBase) = - entity.getActivePotionEffect(Potion.getPotionFromResourceLocation("invisibility")) == null && + private def isVisible(entity: LivingEntity) = + entity.getEffect(Effects.INVISIBILITY) == null && // Note: it only working in lit conditions works and is neat, but this // is pseudo-infrared driven (it only works for *living* entities, after // all), so I think it makes more sense for it to work in the dark, too. /* entity.getBrightness(0) > 0.2 && */ { - val target = entity.getPositionVector - isClearPath(target) || isClearPath(target.addVector(0.0D, entity.getEyeHeight, 0.0D)) + val target = entity.position + isClearPath(target) || isClearPath(target.add(0.0D, entity.getEyeHeight, 0.0D)) } - private def sendSignal(entity: EntityLivingBase) { + private def sendSignal(entity: LivingEntity) { if (Settings.get.inputUsername) { - node.sendToReachable("computer.signal", "motion", Double.box(entity.posX - (x + 0.5)), Double.box(entity.posY - (y + 0.5)), Double.box(entity.posZ - (z + 0.5)), entity.getName) + node.sendToReachable("computer.signal", "motion", Double.box(entity.getX - (x + 0.5)), Double.box(entity.getY - (y + 0.5)), Double.box(entity.getZ - (z + 0.5)), entity.getName.getString) } else { - node.sendToReachable("computer.signal", "motion", Double.box(entity.posX - (x + 0.5)), Double.box(entity.posY - (y + 0.5)), Double.box(entity.posZ - (z + 0.5))) + node.sendToReachable("computer.signal", "motion", Double.box(entity.getX - (x + 0.5)), Double.box(entity.getY - (y + 0.5)), Double.box(entity.getZ - (z + 0.5))) } } @@ -138,14 +141,14 @@ class MotionSensor(val host: EnvironmentHost) extends prefab.AbstractManagedEnvi private final val SensitivityTag = Settings.namespace + "sensitivity" - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) sensitivity = nbt.getDouble(SensitivityTag) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setDouble(SensitivityTag, sensitivity) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putDouble(SensitivityTag, sensitivity) } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/server/component/NetworkCard.scala b/src/main/scala/li/cil/oc/server/component/NetworkCard.scala index abcfcca447..b8b2376321 100644 --- a/src/main/scala/li/cil/oc/server/component/NetworkCard.scala +++ b/src/main/scala/li/cil/oc/server/component/NetworkCard.scala @@ -23,8 +23,8 @@ import li.cil.oc.common.Tier import li.cil.oc.server.{PacketSender => ServerPacketSender} import net.minecraft.nbt._ -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class NetworkCard(val host: EnvironmentHost) extends AbstractManagedEnvironment with RackBusConnectable with DeviceInfo with traits.WakeMessageAware { @@ -160,17 +160,17 @@ class NetworkCard(val host: EnvironmentHost) extends AbstractManagedEnvironment private final val OpenPortsTag = "openPorts" - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) assert(openPorts.isEmpty) openPorts ++= nbt.getIntArray(OpenPortsTag) loadWakeMessage(nbt) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) - nbt.setIntArray(OpenPortsTag, openPorts.toArray) + nbt.putIntArray(OpenPortsTag, openPorts.toArray) saveWakeMessage(nbt) } diff --git a/src/main/scala/li/cil/oc/server/component/Redstone.scala b/src/main/scala/li/cil/oc/server/component/Redstone.scala index b6571aaf4c..4833882e5d 100644 --- a/src/main/scala/li/cil/oc/server/component/Redstone.scala +++ b/src/main/scala/li/cil/oc/server/component/Redstone.scala @@ -9,7 +9,7 @@ import li.cil.oc.common.tileentity.traits.BundledRedstoneAware import li.cil.oc.common.tileentity.traits.RedstoneAware import li.cil.oc.server.component -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ object Redstone { diff --git a/src/main/scala/li/cil/oc/server/component/RedstoneBundled.scala b/src/main/scala/li/cil/oc/server/component/RedstoneBundled.scala index 61132bf467..8a087ddab1 100644 --- a/src/main/scala/li/cil/oc/server/component/RedstoneBundled.scala +++ b/src/main/scala/li/cil/oc/server/component/RedstoneBundled.scala @@ -11,9 +11,9 @@ import li.cil.oc.api.machine.Arguments import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.common.tileentity.traits.BundledRedstoneAware -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ trait RedstoneBundled extends RedstoneVanilla { private final lazy val deviceInfo = Map( @@ -33,7 +33,7 @@ trait RedstoneBundled extends RedstoneVanilla { override def redstone: EnvironmentHost with BundledRedstoneAware - private def getBundleKey(args: Arguments): (Option[EnumFacing], Option[Int]) = { + private def getBundleKey(args: Arguments): (Option[Direction], Option[Int]) = { args.count match { case 2 => (Option(checkSide(args, 0)), Option(checkColor(args, 1))) case 1 => (Option(checkSide(args, 0)), None) @@ -103,10 +103,10 @@ trait RedstoneBundled extends RedstoneVanilla { def setBundledOutput(context: Context, args: Arguments): Array[AnyRef] = { var ret: AnyRef = null if (getBundleAssignment(args) match { - case (side: EnumFacing, color: Int, value: Int) => + case (side: Direction, color: Int, value: Int) => ret = new java.lang.Integer(redstone.getBundledOutput(side, color)) redstone.setBundledOutput(side, color, value) - case (side: EnumFacing, value: util.Map[_, _], _) => + case (side: Direction, value: util.Map[_, _], _) => ret = redstone.getBundledOutput(side) redstone.setBundledOutput(side, value) case (value: util.Map[_, _], _, _) => diff --git a/src/main/scala/li/cil/oc/server/component/RedstoneSignaller.scala b/src/main/scala/li/cil/oc/server/component/RedstoneSignaller.scala index 117dab5820..fae2b88066 100644 --- a/src/main/scala/li/cil/oc/server/component/RedstoneSignaller.scala +++ b/src/main/scala/li/cil/oc/server/component/RedstoneSignaller.scala @@ -8,7 +8,7 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import scala.collection.mutable.ArrayBuffer @@ -40,7 +40,7 @@ trait RedstoneSignaller extends AbstractManagedEnvironment { val flatArgs = ArrayBuffer[Object]("redstone_changed", side, Int.box(args.oldValue), Int.box(args.newValue)) if (args.color >= 0) flatArgs += Int.box(args.color) - node.sendToReachable("computer.signal", flatArgs: _*) + node.sendToReachable("computer.signal", flatArgs.toArray: _*) if (args.oldValue < wakeThreshold && args.newValue >= wakeThreshold) { if (wakeNeighborsOnly) node.sendToNeighbors("computer.start") @@ -53,13 +53,13 @@ trait RedstoneSignaller extends AbstractManagedEnvironment { private final val WakeThresholdNbt = "wakeThreshold" - override def load(nbt: NBTTagCompound): Unit = { - super.load(nbt) - wakeThreshold = nbt.getInteger(WakeThresholdNbt) + override def loadData(nbt: CompoundNBT): Unit = { + super.loadData(nbt) + wakeThreshold = nbt.getInt(WakeThresholdNbt) } - override def save(nbt: NBTTagCompound): Unit = { - super.save(nbt) - nbt.setInteger(WakeThresholdNbt, wakeThreshold) + override def saveData(nbt: CompoundNBT): Unit = { + super.saveData(nbt) + nbt.putInt(WakeThresholdNbt, wakeThreshold) } } diff --git a/src/main/scala/li/cil/oc/server/component/RedstoneVanilla.scala b/src/main/scala/li/cil/oc/server/component/RedstoneVanilla.scala index ad5ff32388..bcc2f7187a 100644 --- a/src/main/scala/li/cil/oc/server/component/RedstoneVanilla.scala +++ b/src/main/scala/li/cil/oc/server/component/RedstoneVanilla.scala @@ -16,9 +16,10 @@ import li.cil.oc.common.tileentity.traits.{RedstoneAware, RedstoneChangedEventAr import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedBlock._ import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.util.EnumFacing +import li.cil.oc.util.RotationHelper +import net.minecraft.util.Direction -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ trait RedstoneVanilla extends RedstoneSignaller with DeviceInfo { def redstone: EnvironmentHost with RedstoneAware @@ -36,7 +37,7 @@ trait RedstoneVanilla extends RedstoneSignaller with DeviceInfo { override def getDeviceInfo: util.Map[String, String] = deviceInfo - protected val SIDE_RANGE: Array[EnumFacing] = EnumFacing.values + protected val SIDE_RANGE: Array[Direction] = Direction.values // ----------------------------------------------------------------------- // @Callback(direct = true, doc = "function([side:number]):number or table -- Get the redstone input (all sides, or optionally on the specified side)") @@ -59,7 +60,7 @@ trait RedstoneVanilla extends RedstoneSignaller with DeviceInfo { def setOutput(context: Context, args: Arguments): Array[AnyRef] = { var ret: AnyRef = null if (getAssignment(args) match { - case (side: EnumFacing, value: Int) => + case (side: Direction, value: Int) => ret = new java.lang.Integer(redstone.getOutput(side)) redstone.setOutput(side, value) case (value: util.Map[_, _], _) => @@ -78,7 +79,7 @@ trait RedstoneVanilla extends RedstoneSignaller with DeviceInfo { val blockPos = BlockPosition(redstone).offset(side) if (redstone.world.blockExists(blockPos)) { val block = redstone.world.getBlock(blockPos) - if (block.hasComparatorInputOverride(redstone.world.getBlockState(blockPos.toBlockPos))) { + if (redstone.world.getBlockState(blockPos.toBlockPos).hasAnalogOutputSignal) { val comparatorOverride = block.getComparatorInputOverride(blockPos, side.getOpposite) return result(comparatorOverride) } @@ -114,11 +115,11 @@ trait RedstoneVanilla extends RedstoneSignaller with DeviceInfo { } } - protected def checkSide(args: Arguments, index: Int): EnumFacing = { + protected def checkSide(args: Arguments, index: Int): Direction = { val side = args.checkInteger(index) if (side < 0 || side > 5) throw new IllegalArgumentException("invalid side") - redstone.toGlobal(EnumFacing.getFront(side)) + redstone.toGlobal(Direction.from3DDataValue(side)) } private def valuesToMap(ar: Array[Int]): Map[Int, Int] = SIDE_RANGE.map(_.ordinal).map{ case side if side < ar.length => side -> ar(side) }.toMap diff --git a/src/main/scala/li/cil/oc/server/component/RedstoneWireless.scala b/src/main/scala/li/cil/oc/server/component/RedstoneWireless.scala index 5b85bb8c02..c583bdd432 100644 --- a/src/main/scala/li/cil/oc/server/component/RedstoneWireless.scala +++ b/src/main/scala/li/cil/oc/server/component/RedstoneWireless.scala @@ -1,8 +1,5 @@ package li.cil.oc.server.component -import codechicken.lib.vec.Vector3 -import codechicken.wirelessredstone.api.WirelessReceivingDevice -import codechicken.wirelessredstone.api.WirelessTransmittingDevice import li.cil.oc.Constants import li.cil.oc.api.driver.DeviceInfo.DeviceAttribute import li.cil.oc.api.driver.DeviceInfo.DeviceClass @@ -17,16 +14,11 @@ import li.cil.oc.common.EventHandler import li.cil.oc.common.tileentity.traits.RedstoneChangedEventArgs import li.cil.oc.integration.Mods import li.cil.oc.integration.util -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.fml.common.Optional +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ -@Optional.InterfaceList(Array( - new Optional.Interface(iface = "codechicken.wirelessredstone.api.WirelessReceivingDevice", modid = Mods.IDs.WirelessRedstoneCBE), - new Optional.Interface(iface = "codechicken.wirelessredstone.api.WirelessTransmittingDevice", modid = Mods.IDs.WirelessRedstoneCBE) -)) -trait RedstoneWireless extends RedstoneSignaller with WirelessReceivingDevice with WirelessTransmittingDevice with DeviceInfo { +trait RedstoneWireless extends RedstoneSignaller with DeviceInfo { def redstone: EnvironmentHost var wirelessFrequency = 0 @@ -102,28 +94,6 @@ trait RedstoneWireless extends RedstoneSignaller with WirelessReceivingDevice wi // ----------------------------------------------------------------------- // - @Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE) - override def updateDevice(frequency: Int, on: Boolean) { - if (frequency == wirelessFrequency && on != wirelessInput) { - wirelessInput = on - onRedstoneChanged(RedstoneChangedEventArgs(null, if (on) 0 else 1, if (on) 1 else 0)) - } - } - - @Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE) - override def getTransmitPos = new Vector3(redstone.xPosition, redstone.yPosition, redstone.zPosition) - - @Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE) - override def getDimension: Int = redstone.world.provider.getDimension - - @Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE) - override def getFreq: Int = wirelessFrequency - - @Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE) - override def getAttachedEntity = null - - // ----------------------------------------------------------------------- // - override def onConnect(node: Node) { super.onConnect(node) if (node == this.node) { @@ -147,17 +117,17 @@ trait RedstoneWireless extends RedstoneSignaller with WirelessReceivingDevice wi private final val WirelessInputTag = "wirelessInput" private final val WirelessOutputTag = "wirelessOutput" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - wirelessFrequency = nbt.getInteger(WirelessFrequencyTag) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + wirelessFrequency = nbt.getInt(WirelessFrequencyTag) wirelessInput = nbt.getBoolean(WirelessInputTag) wirelessOutput = nbt.getBoolean(WirelessOutputTag) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setInteger(WirelessFrequencyTag, wirelessFrequency) - nbt.setBoolean(WirelessInputTag, wirelessInput) - nbt.setBoolean(WirelessOutputTag, wirelessOutput) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putInt(WirelessFrequencyTag, wirelessFrequency) + nbt.putBoolean(WirelessInputTag, wirelessInput) + nbt.putBoolean(WirelessOutputTag, wirelessOutput) } } diff --git a/src/main/scala/li/cil/oc/server/component/Robot.scala b/src/main/scala/li/cil/oc/server/component/Robot.scala index 0dced123ba..9b71ceec94 100644 --- a/src/main/scala/li/cil/oc/server/component/Robot.scala +++ b/src/main/scala/li/cil/oc/server/component/Robot.scala @@ -23,11 +23,12 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumParticleTypes +import net.minecraft.nbt.CompoundNBT +import net.minecraft.particles.ParticleTypes +import net.minecraft.util.Direction +import net.minecraft.util.ResourceLocation -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with Agent with DeviceInfo { override val node = api.Network.newNode(this, Visibility.Network). @@ -36,14 +37,14 @@ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with create() val romRobot = Option(api.FileSystem.asManagedEnvironment(api.FileSystem. - fromClass(OpenComputers.getClass, Settings.resourceDomain, "lua/component/robot"), "robot")) + fromResource(new ResourceLocation(Settings.resourceDomain, "lua/component/robot")), "robot")) private final lazy val deviceInfo = Map( DeviceAttribute.Class -> DeviceClass.System, DeviceAttribute.Description -> "Robot", DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, DeviceAttribute.Product -> "Caterpillar", - DeviceAttribute.Capacity -> agent.getSizeInventory.toString + DeviceAttribute.Capacity -> agent.getContainerSize.toString ) override def getDeviceInfo: util.Map[String, String] = deviceInfo @@ -73,13 +74,13 @@ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with @Callback(doc = "function():number -- Get the durability of the currently equipped tool.") def durability(context: Context, args: Arguments): Array[AnyRef] = { - StackOption(agent.equipmentInventory.getStackInSlot(0)) match { + StackOption(agent.equipmentInventory.getItem(0)) match { case SomeStack(item) => ToolDurabilityProviders.getDurability(item) match { case Some(durability) => result(durability) - case _ => result(Unit, "tool cannot be damaged") + case _ => result((), "tool cannot be damaged") } - case _ => result(Unit, "no tool equipped") + case _ => result((), "no tool equipped") } } @@ -91,18 +92,18 @@ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with if (agent.isAnimatingMove) { // This shouldn't really happen due to delays being enforced, but just to // be on the safe side... - result(Unit, "already moving") + result((), "already moving") } else { val (something, what) = blockContent(direction) if (something) { context.pause(0.4) - PacketSender.sendParticleEffect(BlockPosition(agent), EnumParticleTypes.CRIT, 8, 0.25, Some(direction)) - result(Unit, what) + PacketSender.sendParticleEffect(BlockPosition(agent), ParticleTypes.CRIT, 8, 0.25, Some(direction)) + result((), what) } else { if (!node.tryChangeBuffer(-Settings.get.robotMoveCost)) { - result(Unit, "not enough energy") + result((), "not enough energy") } else if (agent.move(direction)) { context.pause(Settings.get.moveDelay) @@ -111,8 +112,8 @@ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with else { node.changeBuffer(Settings.get.robotMoveCost) context.pause(0.4) - PacketSender.sendParticleEffect(BlockPosition(agent), EnumParticleTypes.CRIT, 8, 0.25, Some(direction)) - result(Unit, "impossible move") + PacketSender.sendParticleEffect(BlockPosition(agent), ParticleTypes.CRIT, 8, 0.25, Some(direction)) + result((), "impossible move") } } } @@ -122,14 +123,14 @@ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with def turn(context: Context, args: Arguments): Array[AnyRef] = { val clockwise = args.checkBoolean(0) if (node.tryChangeBuffer(-Settings.get.robotTurnCost)) { - if (clockwise) agent.rotate(EnumFacing.UP) - else agent.rotate(EnumFacing.DOWN) + if (clockwise) agent.rotate(Direction.UP) + else agent.rotate(Direction.DOWN) agent.animateTurn(clockwise, Settings.get.turnDelay) context.pause(Settings.get.turnDelay) result(true) } else { - result(Unit, "not enough energy") + result((), "not enough energy") } } @@ -157,13 +158,13 @@ class Robot(val agent: tileentity.Robot) extends AbstractManagedEnvironment with private final val RomRobotTag = "romRobot" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - romRobot.foreach(_.load(nbt.getCompoundTag(RomRobotTag))) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + romRobot.foreach(_.loadData(nbt.getCompound(RomRobotTag))) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - romRobot.foreach(fs => nbt.setNewCompoundTag(RomRobotTag, fs.save)) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + romRobot.foreach(fs => nbt.setNewCompoundTag(RomRobotTag, fs.saveData)) } } diff --git a/src/main/scala/li/cil/oc/server/component/Server.scala b/src/main/scala/li/cil/oc/server/component/Server.scala index 6710a8695d..279f164eaa 100644 --- a/src/main/scala/li/cil/oc/server/component/Server.scala +++ b/src/main/scala/li/cil/oc/server/component/Server.scala @@ -19,32 +19,33 @@ import li.cil.oc.api.network.Analyzable import li.cil.oc.api.network.Environment import li.cil.oc.api.network.Message import li.cil.oc.api.network.Node -import li.cil.oc.common.GuiType import li.cil.oc.common.InventorySlots import li.cil.oc.common.Slot import li.cil.oc.common.Tier +import li.cil.oc.common.container.ContainerTypes import li.cil.oc.common.inventory.ComponentInventory import li.cil.oc.common.inventory.ServerInventory import li.cil.oc.common.item -import li.cil.oc.common.item.Delegator import li.cil.oc.server.network.Connector import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.entity.player.ServerPlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.world.World import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.ICapabilityProvider +import net.minecraftforge.common.util.LazyOptional -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment with MachineHost with ServerInventory with ComponentInventory with Analyzable with internal.Server with ICapabilityProvider with DeviceInfo { lazy val machine: api.machine.Machine = Machine.create(this) - val node: Node = if (!rack.world.isRemote) machine.node else null + val node: Node = if (!rack.world.isClientSide) machine.node else null var wasRunning = false var hadErrored = false @@ -56,7 +57,7 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit DeviceAttribute.Description -> "Server", DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, DeviceAttribute.Product -> "Blader", - DeviceAttribute.Capacity -> getSizeInventory.toString + DeviceAttribute.Capacity -> getContainerSize.toString ) override def getDeviceInfo: util.Map[String, String] = deviceInfo @@ -81,25 +82,25 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit private final val MachineTag = "machine" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - if (!rack.world.isRemote) { - machine.load(nbt.getCompoundTag(MachineTag)) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + if (!rack.world.isClientSide) { + machine.loadData(nbt.getCompound(MachineTag)) } } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - if (!rack.world.isRemote) { - nbt.setNewCompoundTag(MachineTag, machine.save) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + if (!rack.world.isClientSide) { + nbt.setNewCompoundTag(MachineTag, machine.saveData) } } // ----------------------------------------------------------------------- // // MachineHost - override def internalComponents(): Iterable[ItemStack] = (0 until getSizeInventory).collect { - case i if !getStackInSlot(i).isEmpty && isComponentSlot(i, getStackInSlot(i)) => getStackInSlot(i) + override def internalComponents(): Iterable[ItemStack] = (0 until getContainerSize).collect { + case i if !getItem(i).isEmpty && isComponentSlot(i, getItem(i)) => getItem(i) } override def componentSlot(address: String): Int = components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) @@ -124,12 +125,14 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit // ----------------------------------------------------------------------- // // ServerInventory - override def tier: Int = Delegator.subItem(container) match { - case Some(server: item.Server) => server.tier + override def rackSlot = slot + + override def tier: Int = container.getItem match { + case server: item.Server => server.tier case _ => 0 } - override def isUsableByPlayer(player: EntityPlayer): Boolean = rack.isUsableByPlayer(player) + override def stillValid(player: PlayerEntity): Boolean = rack.stillValid(player) && rack.indexOfMountable(this) >= 0 // ----------------------------------------------------------------------- // // ItemStackInventory @@ -139,7 +142,7 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit // ----------------------------------------------------------------------- // // ComponentInventory - override def container: ItemStack = rack.getStackInSlot(slot) + override def container: ItemStack = rack.getItem(slot) override protected def connectItemNode(node: Node) { if (node != null) { @@ -150,7 +153,7 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit override protected def onItemRemoved(slot: Int, stack: ItemStack): Unit = { super.onItemRemoved(slot, stack) - if (!rack.world.isRemote) { + if (!rack.world.isClientSide) { val slotType = InventorySlots.server(tier)(slot).slot if (slotType == Slot.CPU) { machine.stop() @@ -161,12 +164,12 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit // ----------------------------------------------------------------------- // // RackMountable - override def getData: NBTTagCompound = { - val nbt = new NBTTagCompound() - nbt.setBoolean("isRunning", wasRunning) - nbt.setBoolean("hasErrored", hadErrored) - nbt.setLong("lastFileSystemAccess", lastFileSystemAccess) - nbt.setLong("lastNetworkActivity", lastNetworkActivity) + override def getData: CompoundNBT = { + val nbt = new CompoundNBT() + nbt.putBoolean("isRunning", wasRunning) + nbt.putBoolean("hasErrored", hadErrored) + nbt.putLong("lastFileSystemAccess", lastFileSystemAccess) + nbt.putLong("lastNetworkActivity", lastNetworkActivity) nbt } @@ -179,18 +182,20 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit case Some(busConnectable: RackBusConnectable) => busConnectable }.apply(index) - override def onActivate(player: EntityPlayer, hand: EnumHand, heldItem: ItemStack, hitX: Float, hitY: Float): Boolean = { - if (!player.getEntityWorld.isRemote) { - if (player.isSneaking) { - if (!machine.isRunning && isUsableByPlayer(player)) { + override def onActivate(player: PlayerEntity, hand: Hand, heldItem: ItemStack, hitX: Float, hitY: Float): Boolean = { + if (!player.level.isClientSide) { + if (player.isCrouching) { + if (!machine.isRunning && stillValid(player)) { wasRunning = false hadErrored = false machine.start() } } else { - val position = BlockPosition(rack) - player.openGui(OpenComputers, GuiType.ServerInRack.id, world, position.x, GuiType.embedSlot(position.y, slot), position.z) + player match { + case srvPlr: ServerPlayerEntity => ContainerTypes.openServerGui(srvPlr, this, slot) + case _ => + } } } true @@ -202,7 +207,7 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit override def canUpdate: Boolean = true override def update(): Unit = { - if (!rack.world.isRemote) { + if (!rack.world.isClientSide) { machine.update() val isRunning = machine.isRunning @@ -229,17 +234,19 @@ class Server(val rack: api.internal.Rack, val slot: Int) extends Environment wit // ----------------------------------------------------------------------- // // Analyzable - override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) + override def onAnalyze(player: PlayerEntity, side: Direction, hitX: Float, hitY: Float, hitZ: Float) = Array(machine.node) // ----------------------------------------------------------------------- // // ICapabilityProvider - override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = components.exists { - case Some(component: ICapabilityProvider) => component.hasCapability(capability, host.toLocal(facing)) - case _ => false + override def getCapability[T](capability: Capability[T], facing: Direction): LazyOptional[T] = { + for (curr <- components) curr match { + case Some(comp: ICapabilityProvider) => { + val cap = comp.getCapability(capability, host.toLocal(facing)) + if (cap.isPresent) return cap + } + case _ => + } + LazyOptional.empty[T] } - - override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = components.collectFirst { - case Some(component: ICapabilityProvider) if component.hasCapability(capability, host.toLocal(facing)) => component.getCapability[T](capability, host.toLocal(facing)) - }.getOrElse(null.asInstanceOf[T]) } diff --git a/src/main/scala/li/cil/oc/server/component/Tablet.scala b/src/main/scala/li/cil/oc/server/component/Tablet.scala index 5a5258a93a..3bfe8ddffa 100644 --- a/src/main/scala/li/cil/oc/server/component/Tablet.scala +++ b/src/main/scala/li/cil/oc/server/component/Tablet.scala @@ -16,7 +16,7 @@ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.common.item.TabletWrapper -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class Tablet(val tablet: TabletWrapper) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -29,7 +29,7 @@ class Tablet(val tablet: TabletWrapper) extends AbstractManagedEnvironment with DeviceAttribute.Description -> "Tablet", DeviceAttribute.Vendor -> Constants.DeviceInfo.DefaultVendor, DeviceAttribute.Product -> "Jogger", - DeviceAttribute.Capacity -> tablet.getSizeInventory.toString + DeviceAttribute.Capacity -> tablet.getContainerSize.toString ) override def getDeviceInfo: util.Map[String, String] = deviceInfo @@ -37,8 +37,8 @@ class Tablet(val tablet: TabletWrapper) extends AbstractManagedEnvironment with // ----------------------------------------------------------------------- // @Callback(doc = """function():number -- Gets the pitch of the player holding the tablet.""") - def getPitch(context: Context, args: Arguments): Array[AnyRef] = result(tablet.player.rotationPitch) + def getPitch(context: Context, args: Arguments): Array[AnyRef] = result(tablet.player.xRot) @Callback(doc = """function():number -- Gets the yaw of the player holding the tablet.""") - def getYaw(context: Context, args: Arguments): Array[AnyRef] = result(tablet.player.rotationYaw) + def getYaw(context: Context, args: Arguments): Array[AnyRef] = result(tablet.player.yRot) } diff --git a/src/main/scala/li/cil/oc/server/component/Trade.scala b/src/main/scala/li/cil/oc/server/component/Trade.scala index c3c7a8f717..9f4d53e615 100644 --- a/src/main/scala/li/cil/oc/server/component/Trade.scala +++ b/src/main/scala/li/cil/oc/server/component/Trade.scala @@ -9,16 +9,19 @@ import li.cil.oc.api.prefab.AbstractValue import li.cil.oc.common.EventHandler import li.cil.oc.util.InventoryUtils import net.minecraft.entity.Entity -import net.minecraft.entity.IMerchant +import net.minecraft.entity.merchant.IMerchant import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.item.MerchantOffer +import net.minecraft.nbt.CompoundNBT import net.minecraft.tileentity.TileEntity +import net.minecraft.util.ResourceLocation +import net.minecraft.util.RegistryKey import net.minecraft.util.math.BlockPos -import net.minecraft.village.MerchantRecipe -import net.minecraftforge.common.DimensionManager +import net.minecraft.util.registry.Registry +import net.minecraftforge.fml.server.ServerLifecycleHooks -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.ref.WeakReference class Trade(val info: TradeInfo) extends AbstractValue { @@ -30,15 +33,15 @@ class Trade(val info: TradeInfo) extends AbstractValue { def maxRange = Settings.get.tradingRange def isInRange = (info.merchant.get, info.host) match { - case (Some(merchant: Entity), Some(host)) => merchant.getDistanceSq(host.xPosition, host.yPosition, host.zPosition) < maxRange * maxRange + case (Some(merchant: Entity), Some(host)) => merchant.distanceToSqr(host.xPosition, host.yPosition, host.zPosition) < maxRange * maxRange case _ => false } // Queue the load because when load is called we can't access the world yet // and we need to access it to get the Robot's TileEntity / Drone's Entity. - override def load(nbt: NBTTagCompound) = EventHandler.scheduleServer(() => info.load(nbt)) + override def loadData(nbt: CompoundNBT) = EventHandler.scheduleServer(() => info.loadData(nbt)) - override def save(nbt: NBTTagCompound) = info.save(nbt) + override def saveData(nbt: CompoundNBT) = info.saveData(nbt) @Callback(doc = "function():number -- Returns a sort index of the merchant that provides this trade") def getMerchantId(context: Context, arguments: Arguments): Array[AnyRef] = @@ -46,16 +49,16 @@ class Trade(val info: TradeInfo) extends AbstractValue { @Callback(doc = "function():table, table -- Returns the items the merchant wants for this trade.") def getInput(context: Context, arguments: Arguments): Array[AnyRef] = - result(info.recipe.map(_.getItemToBuy.copy()).orNull, - if (info.recipe.exists(_.hasSecondItemToBuy)) info.recipe.map(_.getSecondItemToBuy.copy()).orNull else null) + result(info.recipe.map(_.getCostA.copy()).orNull, + if (info.recipe.exists(!_.getCostB.isEmpty)) info.recipe.map(_.getCostB.copy()).orNull else null) @Callback(doc = "function():table -- Returns the item the merchant offers for this trade.") def getOutput(context: Context, arguments: Arguments): Array[AnyRef] = - result(info.recipe.map(_.getItemToSell.copy()).orNull) + result(info.recipe.map(_.getResult.copy()).orNull) @Callback(doc = "function():boolean -- Returns whether the merchant currently wants to trade this.") def isEnabled(context: Context, arguments: Arguments): Array[AnyRef] = - result(info.merchant.get.exists(merchant => !info.recipe.exists(_.isRecipeDisabled))) // Make sure merchant is neither dead/gone nor the recipe has been disabled. + result(info.merchant.get.exists(merchant => !info.recipe.exists(_.isOutOfStock))) // Make sure merchant is neither dead/gone nor the recipe has been disabled. @Callback(doc = "function():boolean, string -- Returns true when trade succeeds and nil, error when not.") def trade(context: Context, arguments: Arguments): Array[AnyRef] = { @@ -64,15 +67,15 @@ class Trade(val info: TradeInfo) extends AbstractValue { case Some(inventory) => // Make sure merchant hasn't died, it somehow gone or moved out of range and still wants to trade this. info.merchant.get match { - case Some(merchant: Entity) if merchant.isEntityAlive && isInRange => - if (!merchant.isEntityAlive) { + case Some(merchant: Entity) if merchant.isAlive && isInRange => + if (!merchant.isAlive) { result(false, "trader died") } else if (!isInRange) { result(false, "out of range") } else { info.recipe match { case Some(recipe) => - if (recipe.isRecipeDisabled) { + if (recipe.isOutOfStock) { result(false, "trade is disabled") } else { if (!hasRoomForRecipe(inventory, recipe)) { @@ -94,18 +97,18 @@ class Trade(val info: TradeInfo) extends AbstractValue { } } - def hasRoomForRecipe(inventory: IInventory, recipe: MerchantRecipe) : Boolean = { - val remainder = recipe.getItemToSell.copy() + def hasRoomForRecipe(inventory: IInventory, recipe: MerchantOffer) : Boolean = { + val remainder = recipe.getResult.copy() InventoryUtils.insertIntoInventory(remainder, InventoryUtils.asItemHandler(inventory), remainder.getCount, simulate = true) remainder.getCount == 0 } - def completeTrade(inventory: IInventory, recipe: MerchantRecipe, exact: Boolean) : Boolean = { + def completeTrade(inventory: IInventory, recipe: MerchantOffer, exact: Boolean) : Boolean = { // Now we'll check if we have enough items to perform the trade, caching first info.merchant.get match { case Some(merchant) => { - val firstInputStack = recipe.getItemToBuy - val secondInputStack = if (recipe.hasSecondItemToBuy) Option(recipe.getSecondItemToBuy) else None + val firstInputStack = recipe.getCostA + val secondInputStack = if (!recipe.getCostB.isEmpty) Option(recipe.getCostB) else None def containsAccumulativeItemStack(stack: ItemStack) = InventoryUtils.extractFromInventory(stack, inventory, null, simulate = true, exact = exact).getCount == 0 @@ -115,7 +118,7 @@ class Trade(val info: TradeInfo) extends AbstractValue { return false // Now we need to check if we have enough inventory space to accept the item we get for the trade. - val outputStack = recipe.getItemToSell.copy() + val outputStack = recipe.getResult.copy() // We established that out inventory allows to perform the trade, now actually do the trade. InventoryUtils.extractFromInventory(firstInputStack, InventoryUtils.asItemHandler(inventory), exact = exact) @@ -123,7 +126,7 @@ class Trade(val info: TradeInfo) extends AbstractValue { InventoryUtils.insertIntoInventory(outputStack, InventoryUtils.asItemHandler(inventory), outputStack.getCount) // Tell the merchant we used the recipe, so MC can disable it and/or enable more recipes. - merchant.useRecipe(recipe) + merchant.notifyTrade(recipe) true } case _ => false @@ -137,7 +140,7 @@ class TradeInfo(var host: Option[EnvironmentHost], var merchant: WeakReference[I def this(host: EnvironmentHost, merchant: IMerchant, recipeID: Int, merchantID: Int) = this(Option(host), new WeakReference[IMerchant](merchant), recipeID, merchantID) - def recipe = merchant.get.map(_.getRecipes(null).get(recipeID)) + def recipe = merchant.get.map(_.getOffers.get(recipeID)) def inventory = host match { case Some(agent: li.cil.oc.api.internal.Agent) => Option(agent.mainInventory()) @@ -156,7 +159,7 @@ class TradeInfo(var host: Option[EnvironmentHost], var merchant: WeakReference[I private final val RecipeID = "recipeID" private final val MerchantID = "merchantID" - def load(nbt: NBTTagCompound): Unit = { + def loadData(nbt: CompoundNBT): Unit = { val isEntity = nbt.getBoolean(HostIsEntityTag) // If drone we find it again by its UUID, if Robot we know the X/Y/Z of the TileEntity. host = if (isEntity) loadHostEntity(nbt) else loadHostTileEntity(nbt) @@ -164,61 +167,60 @@ class TradeInfo(var host: Option[EnvironmentHost], var merchant: WeakReference[I case Some(merchant: IMerchant) => merchant case _ => null }) - recipeID = nbt.getInteger(RecipeID) - merchantID = if (nbt.hasKey(MerchantID)) nbt.getInteger(MerchantID) else -1 + recipeID = nbt.getInt(RecipeID) + merchantID = if (nbt.contains(MerchantID)) nbt.getInt(MerchantID) else -1 } - def save(nbt: NBTTagCompound): Unit = { + def saveData(nbt: CompoundNBT): Unit = { host match { case Some(entity: Entity) => - nbt.setBoolean(HostIsEntityTag, true) - nbt.setInteger(DimensionIDTag, entity.world.provider.getDimension) - nbt.setLong(HostUUIDLeast, entity.getPersistentID.getLeastSignificantBits) - nbt.setLong(HostUUIDMost, entity.getPersistentID.getMostSignificantBits) + nbt.putBoolean(HostIsEntityTag, true) + nbt.putString(DimensionIDTag, entity.world.dimension.location.toString) + nbt.putLong(HostUUIDLeast, entity.getUUID.getLeastSignificantBits) + nbt.putLong(HostUUIDMost, entity.getUUID.getMostSignificantBits) case Some(tileEntity: TileEntity) => - nbt.setBoolean(HostIsEntityTag, false) - nbt.setInteger(DimensionIDTag, tileEntity.getWorld.provider.getDimension) - nbt.setInteger(HostXTag, tileEntity.getPos.getX) - nbt.setInteger(HostYTag, tileEntity.getPos.getY) - nbt.setInteger(HostZTag, tileEntity.getPos.getZ) + nbt.putBoolean(HostIsEntityTag, false) + nbt.putString(DimensionIDTag, tileEntity.getLevel.dimension.location.toString) + nbt.putInt(HostXTag, tileEntity.getBlockPos.getX) + nbt.putInt(HostYTag, tileEntity.getBlockPos.getY) + nbt.putInt(HostZTag, tileEntity.getBlockPos.getZ) case _ => // Welp! } merchant.get match { case Some(entity: Entity) => - nbt.setLong(MerchantUUIDLeastTag, entity.getPersistentID.getLeastSignificantBits) - nbt.setLong(MerchantUUIDMostTag, entity.getPersistentID.getMostSignificantBits) + nbt.putLong(MerchantUUIDLeastTag, entity.getUUID.getLeastSignificantBits) + nbt.putLong(MerchantUUIDMostTag, entity.getUUID.getMostSignificantBits) case _ => } - nbt.setInteger(RecipeID, recipeID) - nbt.setInteger(MerchantID, merchantID) + nbt.putInt(RecipeID, recipeID) + nbt.putInt(MerchantID, merchantID) } - private def loadEntity(nbt: NBTTagCompound, uuid: UUID): Option[Entity] = { - val dimension = nbt.getInteger(DimensionIDTag) - val world = DimensionManager.getWorld(dimension) + private def loadEntity(nbt: CompoundNBT, uuid: UUID): Option[Entity] = { + val dimension = new ResourceLocation(nbt.getString(DimensionIDTag)) + val dimKey = RegistryKey.create(Registry.DIMENSION_REGISTRY, dimension) + val world = ServerLifecycleHooks.getCurrentServer.getLevel(dimKey) - world.loadedEntityList.find { - case entity: Entity if entity.getPersistentID == uuid => true - case _ => false - } + Option(world.getEntity(uuid)) } - private def loadHostEntity(nbt: NBTTagCompound): Option[EnvironmentHost] = { + private def loadHostEntity(nbt: CompoundNBT): Option[EnvironmentHost] = { loadEntity(nbt, new UUID(nbt.getLong(HostUUIDMost), nbt.getLong(HostUUIDLeast))) match { case Some(entity: Entity with li.cil.oc.api.internal.Agent) => Option(entity: EnvironmentHost) case _ => None } } - private def loadHostTileEntity(nbt: NBTTagCompound): Option[EnvironmentHost] = { - val dimension = nbt.getInteger(DimensionIDTag) - val world = DimensionManager.getWorld(dimension) + private def loadHostTileEntity(nbt: CompoundNBT): Option[EnvironmentHost] = { + val dimension = new ResourceLocation(nbt.getString(DimensionIDTag)) + val dimKey = RegistryKey.create(Registry.DIMENSION_REGISTRY, dimension) + val world = ServerLifecycleHooks.getCurrentServer.getLevel(dimKey) - val x = nbt.getInteger(HostXTag) - val y = nbt.getInteger(HostYTag) - val z = nbt.getInteger(HostZTag) + val x = nbt.getInt(HostXTag) + val y = nbt.getInt(HostYTag) + val z = nbt.getInt(HostZTag) - world.getTileEntity(new BlockPos(x, y, z)) match { + world.getBlockEntity(new BlockPos(x, y, z)) match { case robotProxy: li.cil.oc.common.tileentity.RobotProxy => Option(robotProxy.robot) case agent: li.cil.oc.api.internal.Agent => Option(agent) case null => None diff --git a/src/main/scala/li/cil/oc/server/component/Transposer.scala b/src/main/scala/li/cil/oc/server/component/Transposer.scala index ee91d6b4d6..b2a95beb45 100644 --- a/src/main/scala/li/cil/oc/server/component/Transposer.scala +++ b/src/main/scala/li/cil/oc/server/component/Transposer.scala @@ -18,7 +18,7 @@ import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.language.existentials object Transposer { diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeAngel.scala b/src/main/scala/li/cil/oc/server/component/UpgradeAngel.scala index c11a0e778d..d30cf495a6 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeAngel.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeAngel.scala @@ -13,7 +13,7 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ // Note-to-self: this has a component to allow the robot telling it has the // upgrade. diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeBarcodeReader.scala b/src/main/scala/li/cil/oc/server/component/UpgradeBarcodeReader.scala index 0925a5e3a0..19f36dd26d 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeBarcodeReader.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeBarcodeReader.scala @@ -12,14 +12,14 @@ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagList -import net.minecraft.util.EnumFacing -import net.minecraft.world.WorldServer +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.ListNBT +import net.minecraft.util.Direction +import net.minecraft.world.server.ServerWorld -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeBarcodeReader(val host: EnvironmentHost) extends AbstractManagedEnvironment with DeviceInfo { override val node = api.Network.newNode(this, Visibility.Network). @@ -40,8 +40,8 @@ class UpgradeBarcodeReader(val host: EnvironmentHost) extends AbstractManagedEnv super.onMessage(message) if (message.name == "tablet.use") message.source.host match { case machine: api.machine.Machine => (machine.host, message.data) match { - case (tablet: internal.Tablet, Array(nbt: NBTTagCompound, stack: ItemStack, player: EntityPlayer, blockPos: BlockPosition, side: EnumFacing, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => - host.world.getTileEntity(blockPos) match { + case (tablet: internal.Tablet, Array(nbt: CompoundNBT, stack: ItemStack, player: PlayerEntity, blockPos: BlockPosition, side: Direction, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => + host.world.getBlockEntity(blockPos) match { case analyzable: Analyzable => processNodes(analyzable.onAnalyze(player, side, hitX.toFloat, hitY.toFloat, hitZ.toFloat), nbt) case host: SidedEnvironment => @@ -56,25 +56,25 @@ class UpgradeBarcodeReader(val host: EnvironmentHost) extends AbstractManagedEnv } } - private def processNodes(nodes: Array[Node], nbt: NBTTagCompound): Unit = if (nodes != null) { - val readerNBT = new NBTTagList() + private def processNodes(nodes: Array[Node], nbt: CompoundNBT): Unit = if (nodes != null) { + val readerNBT = new ListNBT() for (node <- nodes if node != null) { - val nodeNBT = new NBTTagCompound() + val nodeNBT = new CompoundNBT() node match { case component: Component => - nodeNBT.setString("type", component.name) + nodeNBT.putString("type", component.name) case _ => } val address = node.address() if (address != null && !address.isEmpty) { - nodeNBT.setString("address", node.address()) + nodeNBT.putString("address", node.address()) } - readerNBT.appendTag(nodeNBT) + readerNBT.add(nodeNBT) } - nbt.setTag("analyzed", readerNBT) + nbt.put("analyzed", readerNBT) } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeBattery.scala b/src/main/scala/li/cil/oc/server/component/UpgradeBattery.scala index 8f3d3ceb71..ca614dd792 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeBattery.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeBattery.scala @@ -12,7 +12,7 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeBattery(val tier: Int) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala b/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala index 624ee4eb61..01f13a8f29 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeChunkloader.scala @@ -17,11 +17,12 @@ import li.cil.oc.api.network._ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.common.event.ChunkloaderUpgradeHandler -import net.minecraftforge.common.ForgeChunkManager -import net.minecraftforge.common.ForgeChunkManager.Ticket import net.minecraft.entity.Entity +import net.minecraft.util.math.ChunkPos +import net.minecraft.world.World +import net.minecraft.world.server.ServerWorld -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeChunkloader(val host: EnvironmentHost) extends AbstractManagedEnvironment with DeviceInfo { override val node = api.Network.newNode(this, Visibility.Network). @@ -38,17 +39,19 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends AbstractManagedEnvir override def getDeviceInfo: util.Map[String, String] = deviceInfo - var ticket: Option[Ticket] = None + var ticket: Option[ChunkPos] = None override val canUpdate = true override def update() { super.update() - if (host.world.getTotalWorldTime % Settings.get.tickFrequency == 0 && ticket.isDefined) { + if (host.world.getGameTime % Settings.get.tickFrequency == 0 && ticket.isDefined) { if (!node.tryChangeBuffer(-Settings.get.chunkloaderCost * Settings.get.tickFrequency)) { - ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch { - case _: Throwable => // Ignored. - }) + host.world match { + case world: ServerWorld => { + ticket.foreach(pos => ChunkloaderUpgradeHandler.releaseTicket(world, node.address, pos)) + } + } ticket = None } else if (host.isInstanceOf[Entity]) // Robot move events are not fired for entities (drones) @@ -65,15 +68,15 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends AbstractManagedEnvir override def onConnect(node: Node) { super.onConnect(node) if (node == this.node) { - val restoredTicket = ChunkloaderUpgradeHandler.restoredTickets.remove(node.address) + val restoredTicket = ChunkloaderUpgradeHandler.claimTicket(node.address) if (restoredTicket.isDefined) { if (!isDimensionAllowed) { - try ForgeChunkManager.releaseTicket(restoredTicket.get) catch { - case _: Throwable => // Ignored. + host.world match { + case world: ServerWorld => ChunkloaderUpgradeHandler.releaseTicket(world, node.address, restoredTicket.get) } - OpenComputers.log.info(s"Releasing chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in blacklisted dimension ${host.world().provider.getDimension}.") + OpenComputers.log.info(s"Releasing chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in blacklisted dimension ${host.world().dimension}.") } else { - OpenComputers.log.info(s"Reclaiming chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in dimension ${host.world().provider.getDimension}.") + OpenComputers.log.info(s"Reclaiming chunk loader ticket at (${host.xPosition()}, ${host.yPosition()}, ${host.zPosition()}) in dimension ${host.world().dimension}.") ticket = restoredTicket ChunkloaderUpgradeHandler.updateLoadedChunk(this) } @@ -87,8 +90,8 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends AbstractManagedEnvir override def onDisconnect(node: Node) { super.onDisconnect(node) if (node == this.node) { - ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch { - case _: Throwable => // Ignored. + ticket.foreach(pos => host.world match { + case world: ServerWorld => ChunkloaderUpgradeHandler.releaseTicket(world, node.address, pos) }) ticket = None } @@ -110,8 +113,8 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends AbstractManagedEnvir ticket.isDefined } else if (!enabled && ticket.isDefined) { - ticket.foreach(ticket => try ForgeChunkManager.releaseTicket(ticket) catch { - case _: Throwable => // Ignored. + ticket.foreach(pos => host.world match { + case world: ServerWorld => ChunkloaderUpgradeHandler.releaseTicket(world, node.address, pos) }) ticket = None true @@ -120,8 +123,14 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends AbstractManagedEnvir } } + @Deprecated private def isDimensionAllowed: Boolean = { - val id: Int = host.world().provider.getDimension + val id: Int = host.world().dimension match { + case World.OVERWORLD => 0 + case World.NETHER => -1 + case World.END => 1 + case _ => throw new Error("deprecated") + } val whitelist = Settings.get.chunkloadDimensionWhitelist val blacklist = Settings.get.chunkloadDimensionBlacklist if (!whitelist.isEmpty) { @@ -142,7 +151,8 @@ class UpgradeChunkloader(val host: EnvironmentHost) extends AbstractManagedEnvir throw new Exception("this dimension is blacklisted") } } else { - ticket = Option(ForgeChunkManager.requestTicket(OpenComputers, host.world, ForgeChunkManager.Type.NORMAL)) + // This ticket is a lie, but ChunkloaderUpgradeHandler won't crash or load it. + ticket = Some(new ChunkPos(0, 0)) ChunkloaderUpgradeHandler.updateLoadedChunk(this) } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala b/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala index cdae85f859..2b454c4248 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeCrafting.scala @@ -15,12 +15,14 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.network._ import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.InventoryUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.crafting.IRecipeType +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory -import net.minecraft.inventory.{IInventory, InventoryCraftResult, SlotCrafting} -import net.minecraft.item.crafting.CraftingManager +import net.minecraft.inventory.{CraftResultInventory, IInventory} +import net.minecraft.inventory.container.Container +import net.minecraft.inventory.container.CraftingResultSlot -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -42,29 +44,30 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends Abs result(CraftingInventory.craft(count): _*) } - private object CraftingInventory extends inventory.InventoryCrafting(new inventory.Container { - override def canInteractWith(player: EntityPlayer) = true + private object CraftingInventory extends inventory.CraftingInventory(new Container(null, 0) { + override def stillValid(player: PlayerEntity) = true }, 3, 3) { def craft(wantedCount: Int): Seq[_] = { val player = host.player copyItemsFromHost(player.inventory) var countCrafted = 0 - val initialCraft = CraftingManager.findMatchingRecipe(CraftingInventory, host.world) - if (initialCraft != null) { + val manager = host.world.getRecipeManager + val initialCraft = manager.getRecipeFor(IRecipeType.CRAFTING, CraftingInventory: inventory.CraftingInventory, host.world) + if (initialCraft.isPresent) { def tryCraft() : Boolean = { - val craft = CraftingManager.findMatchingRecipe(CraftingInventory, host.world) - if (craft == null || craft != initialCraft) { + val craft = manager.getRecipeFor(IRecipeType.CRAFTING, CraftingInventory: inventory.CraftingInventory, host.world) + if (craft != initialCraft) { return false } - val craftResult = new InventoryCraftResult - val craftingSlot = new SlotCrafting(player, CraftingInventory, craftResult, 0, 0, 0) - val craftedResult = craft.getCraftingResult(this) - craftResult.setInventorySlotContents(0, craftedResult) - if (!craftingSlot.getHasStack) + val craftResult = new CraftResultInventory + val craftingSlot = new CraftingResultSlot(player, CraftingInventory, craftResult, 0, 0, 0) + val craftedResult = craft.get.assemble(this) + craftResult.setItem(0, craftedResult) + if (!craftingSlot.hasItem) return false - val stack = craftingSlot.decrStackSize(1) + val stack = craftingSlot.remove(1) countCrafted += stack.getCount max 1 val taken = craftingSlot.onTake(player, stack) copyItemsToHost(player.inventory) @@ -82,15 +85,15 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends Abs } def copyItemsFromHost(inventory: IInventory) { - for (slot <- 0 until getSizeInventory) { - val stack = inventory.getStackInSlot(toParentSlot(slot)) - setInventorySlotContents(slot, stack) + for (slot <- 0 until getContainerSize) { + val stack = inventory.getItem(toParentSlot(slot)) + setItem(slot, stack) } } def copyItemsToHost(inventory: IInventory) { - for (slot <- 0 until getSizeInventory) { - inventory.setInventorySlotContents(toParentSlot(slot), getStackInSlot(slot)) + for (slot <- 0 until getContainerSize) { + inventory.setItem(toParentSlot(slot), getItem(slot)) } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala b/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala index 13d86017da..05e33b04ac 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeDatabase.scala @@ -22,7 +22,7 @@ import li.cil.oc.util.StackOption import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeDatabase(val data: IInventory) extends AbstractManagedEnvironment with internal.Database with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -39,20 +39,20 @@ class UpgradeDatabase(val data: IInventory) extends AbstractManagedEnvironment w override def getDeviceInfo: util.Map[String, String] = deviceInfo - override def size = data.getSizeInventory + override def size = data.getContainerSize - override def getStackInSlot(slot: Int) = StackOption(data.getStackInSlot(slot)).map(_.copy()).orEmpty + override def getStackInSlot(slot: Int) = StackOption(data.getItem(slot)).map(_.copy()).orEmpty - override def setStackInSlot(slot: Int, stack: ItemStack) = data.setInventorySlotContents(slot, stack) + override def setStackInSlot(slot: Int, stack: ItemStack) = data.setItem(slot, stack) override def findStackWithHash(needle: String) = indexOf(needle) @Callback(doc = "function(slot:number):table -- Get the representation of the item stack stored in the specified slot.") - def get(context: Context, args: Arguments): Array[AnyRef] = result(data.getStackInSlot(args.checkSlot(data, 0))) + def get(context: Context, args: Arguments): Array[AnyRef] = result(data.getItem(args.checkSlot(data, 0))) @Callback(doc = "function(slot:number):string -- Computes a hash value for the item stack in the specified slot.") def computeHash(context: Context, args: Arguments): Array[AnyRef] = { - data.getStackInSlot(args.checkSlot(data, 0)) match { + data.getItem(args.checkSlot(data, 0)) match { case stack: ItemStack => val hash = Hashing.sha256().hashBytes(ItemUtils.saveStack(stack)) result(hash.toString) @@ -66,19 +66,19 @@ class UpgradeDatabase(val data: IInventory) extends AbstractManagedEnvironment w @Callback(doc = "function(slot:number):boolean -- Clears the specified slot. Returns true if there was something in the slot before.") def clear(context: Context, args: Arguments): Array[AnyRef] = { val slot = args.checkSlot(data, 0) - val nonEmpty = data.getStackInSlot(slot) != ItemStack.EMPTY // zero size stacks - data.setInventorySlotContents(slot, ItemStack.EMPTY) + val nonEmpty = data.getItem(slot) != ItemStack.EMPTY // zero size stacks + data.setItem(slot, ItemStack.EMPTY) result(nonEmpty) } @Callback(doc = "function(fromSlot:number, toSlot:number[, address:string]):boolean -- Copies an entry to another slot, optionally to another database. Returns true if something was overwritten.") def copy(context: Context, args: Arguments): Array[AnyRef] = { val fromSlot = args.checkSlot(data, 0) - val entry = data.getStackInSlot(fromSlot) + val entry = data.getItem(fromSlot) def set(inventory: IInventory) = { val toSlot = args.checkSlot(inventory, 1) - val nonEmpty = inventory.getStackInSlot(toSlot) != ItemStack.EMPTY // zero size stacks - inventory.setInventorySlotContents(toSlot, entry.copy()) + val nonEmpty = inventory.getItem(toSlot) != ItemStack.EMPTY // zero size stacks + inventory.setItem(toSlot, entry.copy()) result(nonEmpty) } if (args.count > 2) DatabaseAccess.withDatabase(node, args.checkString(2), database => set(database.data)) @@ -88,9 +88,9 @@ class UpgradeDatabase(val data: IInventory) extends AbstractManagedEnvironment w @Callback(doc = "function(address:string):number -- Copies the data stored in this database to another database with the specified address.") def clone(context: Context, args: Arguments): Array[AnyRef] = { DatabaseAccess.withDatabase(node, args.checkString(0), database => { - val numberToCopy = math.min(data.getSizeInventory, database.data.getSizeInventory) + val numberToCopy = math.min(data.getContainerSize, database.data.getContainerSize) for (slot <- 0 until numberToCopy) { - database.data.setInventorySlotContents(slot, data.getStackInSlot(slot).copy()) + database.data.setItem(slot, data.getItem(slot).copy()) } context.pause(0.25) result(numberToCopy) @@ -98,7 +98,7 @@ class UpgradeDatabase(val data: IInventory) extends AbstractManagedEnvironment w } private def indexOf(needle: String, offset: Int = 0): Int = { - for (slot <- 0 until data.getSizeInventory) data.getStackInSlot(slot) match { + for (slot <- 0 until data.getContainerSize) data.getItem(slot) match { case stack: ItemStack => val hash = Hashing.sha256().hashBytes(ItemUtils.saveStack(stack)) if (hash.toString == needle) return slot + offset diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeExperience.scala b/src/main/scala/li/cil/oc/server/component/UpgradeExperience.scala index 6f2c7f4546..c830f98a6b 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeExperience.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeExperience.scala @@ -15,14 +15,14 @@ import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab.AbstractManagedEnvironment -import li.cil.oc.util.UpgradeExperience +import li.cil.oc.util.{UpgradeExperience => ExperienceUtil} import net.minecraft.enchantment.EnchantmentHelper -import net.minecraft.entity.item.EntityXPOrb -import net.minecraft.init.Items -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.entity.item.ExperienceOrbEntity +import net.minecraft.item.Items +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends AbstractManagedEnvironment with DeviceInfo { final val MaxLevel = 30 @@ -46,7 +46,7 @@ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends A var level = 0 - def xpForNextLevel: Double = UpgradeExperience.xpForLevel(level + 1) + def xpForNextLevel: Double = ExperienceUtil.xpForLevel(level + 1) def addExperience(value: Double) { if (level < MaxLevel) { @@ -55,10 +55,10 @@ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends A updateXpInfo() } val world = this.host.world - val pos = this.host.player.getPosition - val orb = new EntityXPOrb(world, pos.getX.toDouble + 0.5D, pos.getY.toDouble + 0.5D, pos.getZ.toDouble + 0.5D, value.toInt) - this.host.player.xpCooldown = 0 - orb.onCollideWithPlayer(this.host.player) + val pos = this.host.player.blockPosition + val orb = new ExperienceOrbEntity(world, pos.getX.toDouble + 0.5D, pos.getY.toDouble + 0.5D, pos.getZ.toDouble + 0.5D, value.toInt) + this.host.player.takeXpDelay = 0 + orb.playerTouch(this.host.player) } } @@ -66,7 +66,7 @@ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends A // xp(level) = base + (level * const) ^ exp // pow(xp(level) - base, 1/exp) / const = level val oldLevel = level - level = UpgradeExperience.calculateLevelFromExperience(experience) + level = ExperienceUtil.calculateLevelFromExperience(experience) if (node != null) { if (level != oldLevel) { updateClient() @@ -77,34 +77,34 @@ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends A @Callback(direct = true, doc = """function():number -- The current level of experience stored in this experience upgrade.""") def level(context: Context, args: Arguments): Array[AnyRef] = - result(UpgradeExperience.calculateExperienceLevel(level, experience)) + result(ExperienceUtil.calculateExperienceLevel(level, experience)) @Callback(doc = """function():boolean -- Tries to consume an enchanted item to add experience to the upgrade.""") def consume(context: Context, args: Arguments): Array[AnyRef] = { if (level >= MaxLevel) { - return result(Unit, "max level") + return result((), "max level") } - val stack = host.mainInventory.getStackInSlot(host.selectedSlot) + val stack = host.mainInventory.getItem(host.selectedSlot) if (stack.isEmpty) { - return result(Unit, "no item") + return result((), "no item") } var xp = 0 if (stack.getItem == Items.EXPERIENCE_BOTTLE) { - xp += 3 + host.world.rand.nextInt(5) + host.world.rand.nextInt(5) + xp += 3 + host.world.random.nextInt(5) + host.world.random.nextInt(5) } else { for ((enchantment, level) <- EnchantmentHelper.getEnchantments(stack)) { if (enchantment != null) { - xp += enchantment.getMinEnchantability(level) + xp += enchantment.getMinCost(level) } } if (xp <= 0) { - return result(Unit, "could not extract experience from item") + return result((), "could not extract experience from item") } } - val consumed = host.mainInventory().decrStackSize(host.selectedSlot, 1) + val consumed = host.mainInventory().removeItem(host.selectedSlot, 1) if (consumed.isEmpty) { - return result(Unit, "could not consume item") + return result((), "could not consume item") } addExperience(xp * Settings.get.constantXpGrowth) result(true) @@ -115,14 +115,14 @@ class UpgradeExperience(val host: EnvironmentHost with internal.Agent) extends A case _ => } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - UpgradeExperience.setExperience(nbt, experience) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + ExperienceUtil.setExperience(nbt, experience) } - override def load(nbt: NBTTagCompound) { - super.load(nbt) - experience = UpgradeExperience.getExperience(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + experience = ExperienceUtil.getExperience(nbt) updateXpInfo() } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala index bb0443f5c1..da4cb818c4 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeGenerator.scala @@ -18,12 +18,13 @@ import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.StackOption import li.cil.oc.util.StackOption._ -import net.minecraft.entity.item.EntityItem +import net.minecraft.entity.item.ItemEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.tileentity.TileEntityFurnace +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.text.ITextComponent +import net.minecraftforge.common.ForgeHooks -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -50,45 +51,45 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab @Callback(doc = """function([count:number]):boolean -- Tries to insert fuel from the selected slot into the generator's queue.""") def insert(context: Context, args: Arguments): Array[AnyRef] = { val count = args.optInteger(0, 64) - val stack = host.mainInventory.getStackInSlot(host.selectedSlot) - if (stack.isEmpty) return result(Unit, "selected slot is empty") - if (!TileEntityFurnace.isItemFuel(stack)) { - return result(Unit, "selected slot does not contain fuel") + val stack = host.mainInventory.getItem(host.selectedSlot) + if (stack.isEmpty) return result((), "selected slot is empty") + if (ForgeHooks.getBurnTime(stack, null) <= 0) { + return result((), "selected slot does not contain fuel") } - val container: ItemStack = stack.getItem.getContainerItem(stack) + val container: ItemStack = stack.getContainerItem() val inQueue: ItemStack = inventory match { case SomeStack(q) if q != null && q.getCount > 0 => - if (!q.isItemEqual(stack) || !ItemStack.areItemStackTagsEqual(q, stack)) { - return result(Unit, "different fuel type already queued") + if (!q.sameItem(stack) || !ItemStack.tagMatches(q, stack)) { + return result((), "different fuel type already queued") } q case _ => ItemStack.EMPTY } val space = if (inQueue.isEmpty) stack.getMaxStackSize else inQueue.getMaxStackSize - inQueue.getCount if (space == 0) { - return result(Unit, "queue is full") + return result((), "queue is full") } val previousSelectedFuel: ItemStack = stack.copy val insertLimit: Int = math.min(stack.getCount, math.min(space, count)) - val fuelToInsert: ItemStack = stack.splitStack(insertLimit) + val fuelToInsert: ItemStack = stack.split(insertLimit) // remove the fuel from the inventory if (stack.getCount == 0) { - host.mainInventory.setInventorySlotContents(host.selectedSlot, ItemStack.EMPTY) + host.mainInventory.setItem(host.selectedSlot, ItemStack.EMPTY) } else { - host.mainInventory.setInventorySlotContents(host.selectedSlot, stack) + host.mainInventory.setItem(host.selectedSlot, stack) } // add empty containers to inventory if (!container.isEmpty) { container.grow(fuelToInsert.getCount - 1) - if (!host.player.inventory.addItemStackToInventory(container)) { + if (!host.player.inventory.add(container)) { // no containers could be placed in inventory, give back the fuel - host.mainInventory.setInventorySlotContents(host.selectedSlot, previousSelectedFuel) + host.mainInventory.setItem(host.selectedSlot, previousSelectedFuel) return result(false, "no space in inventory for fuel containers") } else if (container.getCount > 0) { // not all the containers could be inserted in the inventory - host.player.entityDropItem(container.copy, -0.25f) + host.player.spawnAtLocation(container.copy, -0.25f) } } @@ -102,7 +103,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab @Callback(doc = """function():number -- Get the size of the item stack in the generator's queue.""") def count(context: Context, args: Arguments): Array[AnyRef] = { inventory match { - case SomeStack(stack) => result(stack.getCount, stack.getItem.getItemStackDisplayName(stack)) + case SomeStack(stack) => result(stack.getCount, stack.getItem.getName(stack).getString) case _ => result(0) } } @@ -120,12 +121,12 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab if (inQueue.isEmpty) { return result(false, "queue is empty") } - val previousSelectedItem: ItemStack = host.mainInventory.getStackInSlot(host.selectedSlot).copy - val emptyContainer: ItemStack = inQueue.getItem.getContainerItem(inQueue) match { + val previousSelectedItem: ItemStack = host.mainInventory.getItem(host.selectedSlot).copy + val emptyContainer: ItemStack = inQueue.getContainerItem match { case requiredContainer if !requiredContainer.isEmpty && requiredContainer.getCount > 0 => previousSelectedItem match { case slotItem: ItemStack if !slotItem.isEmpty && slotItem.getItem == requiredContainer.getItem && - ItemStack.areItemStackTagsEqual(slotItem, requiredContainer) => slotItem.copy + ItemStack.tagMatches(slotItem, requiredContainer) => slotItem.copy case _ => return result(false, "removing this fuel requires the appropriate container in the selected slot") } case _ => ItemStack.EMPTY // nothing to do, nothing required @@ -135,19 +136,19 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab // backup in case of failure val previousQueue = inQueue.copy - val forUser = inQueue.splitStack(removeLimit) + val forUser = inQueue.split(removeLimit) if (!emptyContainer.isEmpty) { - emptyContainer.splitStack(removeLimit) + emptyContainer.split(removeLimit) if (emptyContainer.isEmpty) { - host.mainInventory.setInventorySlotContents(host.selectedSlot, ItemStack.EMPTY) + host.mainInventory.setItem(host.selectedSlot, ItemStack.EMPTY) } else { - host.mainInventory.decrStackSize(host.selectedSlot, removeLimit) + host.mainInventory.removeItem(host.selectedSlot, removeLimit) } } - // addItemStackToInventory splits the input stack by reference - if (!host.player.inventory.addItemStackToInventory(forUser)) { + // add splits the input stack by reference + if (!host.player.inventory.add(forUser)) { // returns false if NO items were inserted - host.mainInventory.setInventorySlotContents(host.selectedSlot, previousSelectedItem) + host.mainInventory.setItem(host.selectedSlot, previousSelectedItem) inventory = StackOption(previousQueue) result (false, "no inventory space available for fuel") } else { @@ -166,7 +167,7 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab super.update() if (remainingTicks <= 0 && inventory.isDefined) { val stack = inventory.get - remainingTicks = TileEntityFurnace.getItemBurnTime(stack) + remainingTicks = ForgeHooks.getBurnTime(stack, null) if (remainingTicks > 0) { updateClient() stack.shrink(1) @@ -198,10 +199,10 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab inventory match { case SomeStack(stack) => val world = host.world - val entity = new EntityItem(world, host.xPosition, host.yPosition, host.zPosition, stack.copy()) - entity.motionY = 0.04 - entity.setPickupDelay(5) - world.spawnEntity(entity) + val entity = new ItemEntity(world, host.xPosition, host.yPosition, host.zPosition, stack.copy()) + entity.setDeltaMovement(entity.getDeltaMovement.add(0, 0.04, 0)) + entity.setPickUpDelay(5) + world.addFreshEntity(entity) inventory = EmptyStack case _ => } @@ -212,23 +213,23 @@ class UpgradeGenerator(val host: EnvironmentHost with internal.Agent) extends Ab private final val InventoryTag = "inventory" private final val RemainingTicksTag = "remainingTicks" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - inventory = StackOption(new ItemStack(nbt.getCompoundTag("inventory"))) - if (nbt.hasKey(InventoryTag)) { - inventory = StackOption(new ItemStack(nbt.getCompoundTag(InventoryTag))) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + inventory = StackOption(ItemStack.of(nbt.getCompound("inventory"))) + if (nbt.contains(InventoryTag)) { + inventory = StackOption(ItemStack.of(nbt.getCompound(InventoryTag))) } - remainingTicks = nbt.getInteger(RemainingTicksTag) + remainingTicks = nbt.getInt(RemainingTicksTag) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) inventory match { - case SomeStack(stack) => nbt.setNewCompoundTag(InventoryTag, stack.writeToNBT) + case SomeStack(stack) => nbt.setNewCompoundTag(InventoryTag, stack.save) case _ => } if (remainingTicks > 0) { - nbt.setInteger(RemainingTicksTag, remainingTicks) + nbt.putInt(RemainingTicksTag, remainingTicks) } } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala b/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala index 56ad8c71c5..c9d3cef93e 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala @@ -19,7 +19,7 @@ import li.cil.oc.common.tileentity import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ object UpgradeInventoryController { @@ -83,11 +83,11 @@ object UpgradeInventoryController { @Callback(doc = """function():boolean -- Swaps the equipped tool with the content of the currently selected inventory slot.""") def equip(context: Context, args: Arguments): Array[AnyRef] = { - if (inventory.getSizeInventory > 0) { - val equipped = host.getStackInSlot(0) - val selected = inventory.getStackInSlot(selectedSlot) - host.setInventorySlotContents(0, selected) - inventory.setInventorySlotContents(selectedSlot, equipped) + if (inventory.getContainerSize > 0) { + val equipped = host.getItem(0) + val selected = inventory.getItem(selectedSlot) + host.setItem(0, selected) + inventory.setItem(selectedSlot, equipped) result(true) } else result(false) diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeLeash.scala b/src/main/scala/li/cil/oc/server/component/UpgradeLeash.scala index 02d58e1f7e..65771661e8 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeLeash.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeLeash.scala @@ -21,13 +21,13 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedNBT._ import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLiving -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagString +import net.minecraft.entity.MobEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.StringNBT import net.minecraftforge.common.util.Constants.NBT -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class UpgradeLeash(val host: Entity) extends AbstractManagedEnvironment with traits.WorldAware with DeviceInfo { @@ -53,18 +53,18 @@ class UpgradeLeash(val host: Entity) extends AbstractManagedEnvironment with tra @Callback(doc = """function(side:number):boolean -- Tries to put an entity on the specified side of the device onto a leash.""") def leash(context: Context, args: Arguments): Array[AnyRef] = { - if (leashedEntities.size >= MaxLeashedEntities) return result(Unit, "too many leashed entities") + if (leashedEntities.size >= MaxLeashedEntities) return result((), "too many leashed entities") val side = args.checkSideAny(0) val nearBounds = position.bounds - val farBounds = nearBounds.offset(side.getFrontOffsetX * 2.0, side.getFrontOffsetY * 2.0, side.getFrontOffsetZ * 2.0) - val bounds = nearBounds.union(farBounds) - entitiesInBounds[EntityLiving](classOf[EntityLiving], bounds).find(_.canBeLeashedTo(fakePlayer)) match { + val farBounds = nearBounds.move(side.getStepX * 2.0, side.getStepY * 2.0, side.getStepZ * 2.0) + val bounds = nearBounds.minmax(farBounds) + entitiesInBounds[MobEntity](classOf[MobEntity], bounds).find(_.canBeLeashed(fakePlayer)) match { case Some(entity) => - entity.setLeashHolder(host, true) - leashedEntities += entity.getUniqueID + entity.setLeashedTo(host, true) + leashedEntities += entity.getUUID context.pause(0.1) result(true) - case _ => result(Unit, "no unleashed entity") + case _ => result((), "no unleashed entity") } } @@ -82,9 +82,9 @@ class UpgradeLeash(val host: Entity) extends AbstractManagedEnvironment with tra } private def unleashAll() { - entitiesInBounds(classOf[EntityLiving], position.bounds.grow(5, 5, 5)).foreach(entity => { - if (leashedEntities.contains(entity.getUniqueID) && entity.getLeashHolder == host) { - entity.clearLeashed(true, false) + entitiesInBounds(classOf[MobEntity], position.bounds.inflate(5, 5, 5)).foreach(entity => { + if (leashedEntities.contains(entity.getUUID) && entity.getLeashHolder == host) { + entity.dropLeash(true, false) } }) leashedEntities.clear() @@ -92,18 +92,18 @@ class UpgradeLeash(val host: Entity) extends AbstractManagedEnvironment with tra private final val LeashedEntitiesTag = "leashedEntities" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - leashedEntities ++= nbt.getTagList(LeashedEntitiesTag, NBT.TAG_STRING). - map((s: NBTTagString) => UUID.fromString(s.getString)) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + leashedEntities ++= nbt.getList(LeashedEntitiesTag, NBT.TAG_STRING). + map((s: StringNBT) => UUID.fromString(s.getAsString)) // Re-acquire leashed entities. Need to do this manually because leashed - // entities only remember their leashee if it's an EntityLivingBase... + // entities only remember their leashee if it's an LivingEntity... EventHandler.scheduleServer(() => { val foundEntities = mutable.Set.empty[UUID] - entitiesInBounds(classOf[EntityLiving], position.bounds.grow(5, 5, 5)).foreach(entity => { - if (leashedEntities.contains(entity.getUniqueID)) { - entity.setLeashHolder(host, true) - foundEntities += entity.getUniqueID + entitiesInBounds(classOf[MobEntity], position.bounds.inflate(5, 5, 5)).foreach(entity => { + if (leashedEntities.contains(entity.getUUID)) { + entity.setLeashedTo(host, true) + foundEntities += entity.getUUID } }) val missing = leashedEntities.diff(foundEntities) @@ -114,8 +114,8 @@ class UpgradeLeash(val host: Entity) extends AbstractManagedEnvironment with tra }) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) nbt.setNewTagList(LeashedEntitiesTag, leashedEntities.map(_.toString)) } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala index b64ded5a1a..8d249309d4 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeMF.scala @@ -17,19 +17,19 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.driver.DriverBlock import li.cil.oc.api.prefab.AbstractManagedEnvironment -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraft.util.math.Vec3d +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3d -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ /** * Mostly stolen from {@link li.cil.oc.common.tileentity.Adapter} * * @author Sangar, Vexatos */ -class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: EnumFacing) extends AbstractManagedEnvironment with ChangeListener with DeviceInfo { +class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: Direction) extends AbstractManagedEnvironment with ChangeListener with DeviceInfo { override val node = api.Network.newNode(this, Visibility.None). withConnector(). create() @@ -57,9 +57,9 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En } private def updateBoundState() { - if (node != null && node.network != null && coord.world.exists(_.provider.getDimension == host.world.provider.getDimension) - && coord.toVec3.distanceTo(new Vec3d(host.xPosition, host.yPosition, host.zPosition)) <= Settings.get.mfuRange) { - host.world.getTileEntity(coord) match { + if (node != null && node.network != null && coord.world.exists(_.dimension == host.world.dimension) + && coord.toVec3.distanceTo(new Vector3d(host.xPosition, host.yPosition, host.zPosition)) <= Settings.get.mfuRange) { + host.world.getBlockEntity(coord) match { case env: TileEntity with api.network.Environment => otherEnv match { case Some(environment: TileEntity) => @@ -72,7 +72,7 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En otherDrv match { case Some((environment, driver)) => node.disconnect(environment.node) - environment.save(blockData.get.data) + environment.saveData(blockData.get.data) Option(environment.node).foreach(_.remove()) otherDrv = None case _ => // Nothing to do here. @@ -101,7 +101,7 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En val environment = newDriver.createEnvironment(world, coord.toBlockPos, dir) if (environment != null) { otherDrv = Some((environment, newDriver)) - blockData = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) + blockData = Some(new BlockData(environment.getClass.getName, new CompoundNBT())) node.connect(environment.node) } } // else: the more things change, the more they stay the same. @@ -112,10 +112,10 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En otherDrv = Some((environment, newDriver)) blockData match { case Some(data) if data.name == environment.getClass.getName => - environment.load(data.data) + environment.loadData(data.data) case _ => } - blockData = Some(new BlockData(environment.getClass.getName, new NBTTagCompound())) + blockData = Some(new BlockData(environment.getClass.getName, new CompoundNBT())) node.connect(environment.node) } } @@ -123,7 +123,7 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En case Some((environment, driver)) => // We had something there, but it's gone now... node.disconnect(environment.node) - environment.save(blockData.get.data) + environment.saveData(blockData.get.data) Option(environment.node).foreach(_.remove()) otherDrv = None case _ => // Nothing before, nothing now. @@ -143,7 +143,7 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En otherDrv match { case Some((environment, driver)) => node.disconnect(environment.node) - environment.save(blockData.get.data) + environment.saveData(blockData.get.data) Option(environment.node).foreach(_.remove()) otherDrv = None case _ => // Nothing to do here. @@ -158,9 +158,9 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En case Some((env, drv)) if env.canUpdate => env.update() case _ => // No driver } - if (host.world.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (host.world.getGameTime % Settings.get.tickFrequency == 0) { if (!node.tryChangeBuffer(-Settings.get.mfuCost * Settings.get.tickFrequency - * coord.toVec3.distanceTo(new Vec3d(host.xPosition, host.yPosition, host.zPosition)))) { + * coord.toVec3.distanceTo(new Vector3d(host.xPosition, host.yPosition, host.zPosition)))) { disconnect() } } @@ -191,30 +191,30 @@ class UpgradeMF(val host: EnvironmentHost, val coord: BlockPosition, val dir: En } } - override def load(nbt: NBTTagCompound) { - super.load(nbt) - Option(nbt.getCompoundTag(Settings.namespace + "adapter.block")) match { - case Some(blockNbt: NBTTagCompound) => - if (blockNbt.hasKey("name") && blockNbt.hasKey("data")) { - blockData = Some(new BlockData(blockNbt.getString("name"), blockNbt.getCompoundTag("data"))) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + Option(nbt.getCompound(Settings.namespace + "adapter.block")) match { + case Some(blockNbt: CompoundNBT) => + if (blockNbt.contains("name") && blockNbt.contains("data")) { + blockData = Some(new BlockData(blockNbt.getString("name"), blockNbt.getCompound("data"))) } case _ => // Invalid tag } } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - val blockNbt = new NBTTagCompound() + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + val blockNbt = new CompoundNBT() blockData.foreach({ data => - otherDrv.foreach(_._1.save(data.data)) - blockNbt.setString("name", data.name) - blockNbt.setTag("data", data.data) + otherDrv.foreach(_._1.saveData(data.data)) + blockNbt.putString("name", data.name) + blockNbt.put("data", data.data) }) - nbt.setTag(Settings.namespace + "adapter.block", blockNbt) + nbt.put(Settings.namespace + "adapter.block", blockNbt) } // ----------------------------------------------------------------------- // - private class BlockData(val name: String, val data: NBTTagCompound) + private class BlockData(val name: String, val data: CompoundNBT) } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala b/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala index cbe4eee21c..5f958b1f34 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeNavigation.scala @@ -22,12 +22,12 @@ import li.cil.oc.common.item.data.NavigationUpgradeData import li.cil.oc.common.Tier import li.cil.oc.server.network.Waypoints import li.cil.oc.util.BlockPosition -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumFacing +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.Direction -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeNavigation(val host: EnvironmentHost with Rotatable) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -53,13 +53,13 @@ class UpgradeNavigation(val host: EnvironmentHost with Rotatable) extends Abstra def getPosition(context: Context, args: Arguments): Array[AnyRef] = { val info = data.mapData(host.world) val size = data.getSize(host.world) - val relativeX = host.xPosition - info.xCenter - val relativeZ = host.zPosition - info.zCenter + val relativeX = host.xPosition - info.x + val relativeZ = host.zPosition - info.z if (math.abs(relativeX) <= size / 2 && math.abs(relativeZ) <= size / 2) result(relativeX, host.yPosition, relativeZ) else - result(Unit, "out of range") + result((), "out of range") } @Callback(doc = """function():number -- Get the current orientation of the robot.""") @@ -72,13 +72,13 @@ class UpgradeNavigation(val host: EnvironmentHost with Rotatable) extends Abstra def findWaypoints(context: Context, args: Arguments): Array[AnyRef] = { val range = args.checkDouble(0) max 0 min Settings.get.maxWirelessRange(Tier.Two) if (range <= 0) return result(Array.empty) - if (!node.tryChangeBuffer(-range * Settings.get.wirelessCostPerRange(Tier.Two) * 0.25)) return result(Unit, "not enough energy") + if (!node.tryChangeBuffer(-range * Settings.get.wirelessCostPerRange(Tier.Two) * 0.25)) return result((), "not enough energy") context.pause(0.5) val position = BlockPosition(host) val positionVec = position.toVec3 val rangeSq = range * range val waypoints = Waypoints.findWaypoints(position, range). - filter(waypoint => waypoint.getDistanceSq(positionVec.x, positionVec.y, positionVec.z) <= rangeSq) + filter(waypoint => positionVec.distanceToSqr(waypoint.x + 0.5, waypoint.y + 0.5, waypoint.z + 0.5) <= rangeSq) result(waypoints.map(waypoint => { val delta = waypoint.position.offset(waypoint.facing).toVec3.subtract(positionVec) Map( @@ -94,11 +94,11 @@ class UpgradeNavigation(val host: EnvironmentHost with Rotatable) extends Abstra super.onMessage(message) if (message.name == "tablet.use") message.source.host match { case machine: api.machine.Machine => (machine.host, message.data) match { - case (tablet: internal.Tablet, Array(nbt: NBTTagCompound, stack: ItemStack, player: EntityPlayer, blockPos: BlockPosition, side: EnumFacing, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => + case (tablet: internal.Tablet, Array(nbt: CompoundNBT, stack: ItemStack, player: PlayerEntity, blockPos: BlockPosition, side: Direction, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => val info = data.mapData(host.world) - nbt.setInteger("posX", blockPos.x - info.xCenter) - nbt.setInteger("posY", blockPos.y) - nbt.setInteger("posZ", blockPos.z - info.zCenter) + nbt.putInt("posX", blockPos.x - info.x) + nbt.putInt("posY", blockPos.y) + nbt.putInt("posZ", blockPos.z - info.z) case _ => // Ignore. } case _ => // Ignore. @@ -107,13 +107,13 @@ class UpgradeNavigation(val host: EnvironmentHost with Rotatable) extends Abstra // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { - super.load(nbt) - data.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + data.loadData(nbt) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - data.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + data.saveData(nbt) } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala b/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala index a1ac268d18..a3831fde2b 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradePiston.scala @@ -16,34 +16,36 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ -import net.minecraft.block.BlockPistonBase -import net.minecraft.init.SoundEvents -import net.minecraft.util.{EnumFacing, SoundCategory} +import net.minecraft.block.Blocks +import net.minecraft.block.PistonBlock +import net.minecraft.util.SoundEvents +import net.minecraft.util.{Direction, SoundCategory} +import net.minecraft.util.math.BlockPos import li.cil.oc.server.{PacketSender => ServerPacketSender} -import net.minecraft.block.material.EnumPushReaction +import net.minecraft.block.material.PushReaction -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ protected object PistonTraits { trait ExtendAware { val host: EnvironmentHost - def pushOrigin(side: EnumFacing): BlockPosition = BlockPosition(host) - def pushDirection(args: Arguments, index: Int): EnumFacing + def pushOrigin(side: Direction): BlockPosition = BlockPosition(host) + def pushDirection(args: Arguments, index: Int): Direction } trait DroneLike extends ExtendAware { - def pushDirection(args: Arguments, index: Int): EnumFacing = args.optSideAny(index, EnumFacing.SOUTH) + def pushDirection(args: Arguments, index: Int): Direction = args.optSideAny(index, Direction.SOUTH) } trait RotatableLike extends ExtendAware { val rotatable: internal.Rotatable with EnvironmentHost - def pushDirection(args: Arguments, index: Int): EnumFacing = rotatable.toGlobal(args.optSideForAction(index, EnumFacing.SOUTH)) + def pushDirection(args: Arguments, index: Int): Direction = rotatable.toGlobal(args.optSideForAction(index, Direction.SOUTH)) } trait TabletLike extends ExtendAware { val tablet: internal.Tablet - override def pushOrigin(side: EnumFacing): BlockPosition = - if (side == EnumFacing.DOWN && tablet.player.getEyeHeight > 1) super.pushOrigin(side).offset(EnumFacing.DOWN) + override def pushOrigin(side: Direction): BlockPosition = + if (side == Direction.DOWN && tablet.player.getEyeHeight > 1) super.pushOrigin(side).offset(Direction.DOWN) else super.pushOrigin(side) } } @@ -68,10 +70,10 @@ abstract class UpgradePiston(val host: EnvironmentHost) extends AbstractManagedE @Callback(doc = """function():boolean -- Returns true if the piston is sticky, i.e. it can also pull.""") def isSticky(context: Context, args: Arguments): Array[AnyRef] = result(isSticky) - protected def doPistonAction(context: Context, side: EnumFacing, extending: Boolean): Array[AnyRef] = { - val sound = if (extending) SoundEvents.BLOCK_PISTON_EXTEND.getRegistryName else SoundEvents.BLOCK_PISTON_CONTRACT.getRegistryName + protected def doPistonAction(context: Context, side: Direction, extending: Boolean): Array[AnyRef] = { + val sound = if (extending) SoundEvents.PISTON_EXTEND.getRegistryName else SoundEvents.PISTON_CONTRACT.getRegistryName val hostPos = pushOrigin(side).toBlockPos - val piston = new BlockPistonBase(isSticky) + val piston = (if (isSticky) Blocks.STICKY_PISTON else Blocks.PISTON).asInstanceOf[PistonBlock] if (!extending) { if (!isSticky) { @@ -79,18 +81,18 @@ abstract class UpgradePiston(val host: EnvironmentHost) extends AbstractManagedE throw new NoSuchMethodError("piston is not sticky. does not have pull") } // make sure that any obstruction block has breaking mobility - val innerBlockPos = hostPos.offset(side) + val innerBlockPos = hostPos.relative(side): BlockPos val innerBlockState = host.world.getBlockState(innerBlockPos) if (innerBlockState != null) { if (!innerBlockState.getBlock.isAir(innerBlockState, host.world, innerBlockPos)) { - if (innerBlockState.getMobilityFlag != EnumPushReaction.DESTROY) { + if (innerBlockState.getPistonPushReaction != PushReaction.DESTROY) { return result(false, "path is obstructed") } } } } - if (piston.doMove(host.world, hostPos, side, extending)) { + if (piston.moveBlocks(host.world, hostPos, side, extending)) { // send piston extend sound to clients host.synchronized(ServerPacketSender.sendSound( host.world, hostPos.getX, hostPos.getY, hostPos.getZ, diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala b/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala index 3b70e3057a..e07a8c6468 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeSign.scala @@ -16,19 +16,19 @@ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.tileentity.TileEntitySign -import net.minecraft.util.EnumFacing -import net.minecraft.util.text.TextComponentString -import net.minecraft.world.WorldServer +import net.minecraft.nbt.CompoundNBT +import net.minecraft.tileentity.SignTileEntity +import net.minecraft.util.Direction +import net.minecraft.util.text.StringTextComponent +import net.minecraft.world.server.ServerWorld import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayerFactory import net.minecraftforge.event.world.BlockEvent -import net.minecraftforge.fml.common.eventhandler.Event +import net.minecraftforge.eventbus.api.Event -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ abstract class UpgradeSign extends AbstractManagedEnvironment with DeviceInfo { private final lazy val deviceInfo = Map( @@ -42,53 +42,53 @@ abstract class UpgradeSign extends AbstractManagedEnvironment with DeviceInfo { def host: EnvironmentHost - protected def getValue(tileEntity: Option[TileEntitySign]): Array[AnyRef] = { + protected def getValue(tileEntity: Option[SignTileEntity]): Array[AnyRef] = { tileEntity match { - case Some(sign) => result(sign.signText.map(_.getUnformattedText).mkString("\n")) - case _ => result(Unit, "no sign") + case Some(sign) => result(sign.messages.map(_.getString).mkString("\n")) + case _ => result((), "no sign") } } - protected def setValue(tileEntity: Option[TileEntitySign], text: String): Array[AnyRef] = { + protected def setValue(tileEntity: Option[SignTileEntity], text: String): Array[AnyRef] = { tileEntity match { case Some(sign) => val player = host match { case robot: internal.Robot => robot.player - case _ => FakePlayerFactory.get(host.world.asInstanceOf[WorldServer], Settings.get.fakePlayerProfile) + case _ => FakePlayerFactory.get(host.world.asInstanceOf[ServerWorld], Settings.get.fakePlayerProfile) } val lines = text.lines.padTo(4, "").map(line => if (line.length > 15) line.substring(0, 15) else line).toArray if (!canChangeSign(player, sign, lines)) { - return result(Unit, "not allowed") + return result((), "not allowed") } - lines.map(line => new TextComponentString(line)).copyToArray(sign.signText) - host.world.notifyBlockUpdate(sign.getPos) + lines.map(line => new StringTextComponent(line)).copyToArray(sign.messages) + host.world.notifyBlockUpdate(sign.getBlockPos) MinecraftForge.EVENT_BUS.post(new SignChangeEvent.Post(sign, lines)) - result(sign.signText.mkString("\n")) - case _ => result(Unit, "no sign") + result(sign.messages.mkString("\n")) + case _ => result((), "no sign") } } - protected def findSign(side: EnumFacing) = { + protected def findSign(side: Direction) = { val hostPos = BlockPosition(host) - host.world.getTileEntity(hostPos) match { - case sign: TileEntitySign => Option(sign) - case _ => host.world.getTileEntity(hostPos.offset(side)) match { - case sign: TileEntitySign => Option(sign) + host.world.getBlockEntity(hostPos) match { + case sign: SignTileEntity => Option(sign) + case _ => host.world.getBlockEntity(hostPos.offset(side)) match { + case sign: SignTileEntity => Option(sign) case _ => None } } } - private def canChangeSign(player: EntityPlayer, tileEntity: TileEntitySign, lines: Array[String]): Boolean = { - if (!host.world.isBlockModifiable(player, tileEntity.getPos)) { + private def canChangeSign(player: PlayerEntity, tileEntity: SignTileEntity, lines: Array[String]): Boolean = { + if (!host.world.mayInteract(player, tileEntity.getBlockPos)) { return false } - val event = new BlockEvent.BreakEvent(host.world, tileEntity.getPos, tileEntity.getWorld.getBlockState(tileEntity.getPos), player) + val event = new BlockEvent.BreakEvent(host.world, tileEntity.getBlockPos, tileEntity.getLevel.getBlockState(tileEntity.getBlockPos), player) MinecraftForge.EVENT_BUS.post(event) if (event.isCanceled || event.getResult == Event.Result.DENY) { return false @@ -103,10 +103,10 @@ abstract class UpgradeSign extends AbstractManagedEnvironment with DeviceInfo { super.onMessage(message) if (message.name == "tablet.use") message.source.host match { case machine: api.machine.Machine => (machine.host, message.data) match { - case (tablet: internal.Tablet, Array(nbt: NBTTagCompound, stack: ItemStack, player: EntityPlayer, blockPos: BlockPosition, side: EnumFacing, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => - host.world.getTileEntity(blockPos) match { - case sign: TileEntitySign => - nbt.setString("signText", sign.signText.map(_.getUnformattedText).mkString("\n")) + case (tablet: internal.Tablet, Array(nbt: CompoundNBT, stack: ItemStack, player: PlayerEntity, blockPos: BlockPosition, side: Direction, hitX: java.lang.Float, hitY: java.lang.Float, hitZ: java.lang.Float)) => + host.world.getBlockEntity(blockPos) match { + case sign: SignTileEntity => + nbt.putString("signText", sign.messages.map(_.getString).mkString("\n")) case _ => } case _ => // Ignore. diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeSolarGenerator.scala b/src/main/scala/li/cil/oc/server/component/UpgradeSolarGenerator.scala index 65a2dd8ce0..0db2b903dc 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeSolarGenerator.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeSolarGenerator.scala @@ -13,9 +13,11 @@ import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.BlockPosition -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.world.World +import net.minecraft.world.biome.Biome.RainType -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeSolarGenerator(val host: EnvironmentHost) extends AbstractManagedEnvironment with DeviceInfo { override val node = Network.newNode(this, Visibility.Network). @@ -53,10 +55,10 @@ class UpgradeSolarGenerator(val host: EnvironmentHost) extends AbstractManagedEn } private def isSunVisible = { - val blockPos = BlockPosition(host).offset(EnumFacing.UP) - host.world.isDaytime && - (!host.world.provider.isNether) && - host.world.canBlockSeeSky(blockPos.toBlockPos) && - (!host.world.getBiome(blockPos.toBlockPos).canRain || (!host.world.isRaining && !host.world.isThundering)) + val blockPos = BlockPosition(host).offset(Direction.UP) + host.world.isDay && + (host.world.dimension != World.NETHER) && + host.world.canSeeSkyFromBelowWater(blockPos.toBlockPos) && + (host.world.getBiome(blockPos.toBlockPos).getPrecipitation == RainType.NONE || (!host.world.isRaining && !host.world.isThundering)) } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeTank.scala b/src/main/scala/li/cil/oc/server/component/UpgradeTank.scala index fec4a7b176..84850fe079 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeTank.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeTank.scala @@ -11,12 +11,13 @@ import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.api.network.Visibility import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.FluidTank import net.minecraftforge.fluids.IFluidTank +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction +import net.minecraftforge.fluids.capability.templates.FluidTank -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ class UpgradeTank(val owner: EnvironmentHost, val capacity: Int) extends AbstractManagedEnvironment with IFluidTank with DeviceInfo { override val node = Network.newNode(this, Visibility.None).create() @@ -35,13 +36,13 @@ class UpgradeTank(val owner: EnvironmentHost, val capacity: Int) extends Abstrac val tank = new FluidTank(capacity) - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) tank.readFromNBT(nbt) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) tank.writeToNBT(nbt) } @@ -53,20 +54,28 @@ class UpgradeTank(val owner: EnvironmentHost, val capacity: Int) extends Abstrac override def getCapacity = tank.getCapacity - override def getInfo = tank.getInfo + override def isFluidValid(stack: FluidStack) = tank.isFluidValid(stack) - override def fill(stack: FluidStack, doFill: Boolean) = { - val amount = tank.fill(stack, doFill) - if (doFill && amount > 0) { + override def fill(stack: FluidStack, action: FluidAction) = { + val amount = tank.fill(stack, action) + if (action.execute && amount > 0) { node.sendToVisible("computer.signal", "tank_changed", Int.box(tankIndex), Int.box(amount)) } amount } - override def drain(maxDrain: Int, doDrain: Boolean) = { - val amount = tank.drain(maxDrain, doDrain) - if (doDrain && amount != null && amount.amount > 0) { - node.sendToVisible("computer.signal", "tank_changed", Int.box(tankIndex), Int.box(-amount.amount)) + override def drain(stack: FluidStack, action: FluidAction) = { + val amount = tank.drain(stack, action) + if (action.execute && amount != null && amount.getAmount > 0) { + node.sendToVisible("computer.signal", "tank_changed", Int.box(tankIndex), Int.box(-amount.getAmount)) + } + amount + } + + override def drain(maxDrain: Int, action: FluidAction) = { + val amount = tank.drain(maxDrain, action) + if (action.execute && amount != null && amount.getAmount > 0) { + node.sendToVisible("computer.signal", "tank_changed", Int.box(tankIndex), Int.box(-amount.getAmount)) } amount } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeTankController.scala b/src/main/scala/li/cil/oc/server/component/UpgradeTankController.scala index 12e8517b69..3402eca90d 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeTankController.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeTankController.scala @@ -17,7 +17,7 @@ import li.cil.oc.common.tileentity import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ object UpgradeTankController { diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeTractorBeam.scala b/src/main/scala/li/cil/oc/server/component/UpgradeTractorBeam.scala index 18cb4bed50..ff4065bd1f 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeTractorBeam.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeTractorBeam.scala @@ -18,12 +18,12 @@ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.BlockPosition import li.cil.oc.util.InventoryUtils -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.item.ItemEntity +import net.minecraft.entity.player.PlayerEntity import net.minecraft.util.math.BlockPos -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ object UpgradeTractorBeam { @@ -45,22 +45,22 @@ object UpgradeTractorBeam { protected def position: BlockPosition - protected def collectItem(item: EntityItem): Unit + protected def collectItem(item: ItemEntity): Unit private def world = position.world.get @Callback(doc = """function():boolean -- Tries to pick up a random item in the robots' vicinity.""") def suck(context: Context, args: Arguments): Array[AnyRef] = { - val items = world.getEntitiesWithinAABB(classOf[EntityItem], position.bounds.grow(pickupRadius, pickupRadius, pickupRadius)) - .filter(item => item.isEntityAlive && !item.cannotPickup) + val items = world.getEntitiesOfClass(classOf[ItemEntity], position.bounds.inflate(pickupRadius, pickupRadius, pickupRadius)) + .filter(item => item.isAlive && !item.hasPickUpDelay) if (items.nonEmpty) { - val item = items(world.rand.nextInt(items.size)) + val item = items(world.random.nextInt(items.size)) val stack = item.getItem val size = stack.getCount collectItem(item) - if (stack.getCount < size || item.isDead) { + if (stack.getCount < size || !item.isAlive) { context.pause(Settings.get.suckDelay) - world.playEvent(2003, new BlockPos(math.floor(item.posX).toInt, math.floor(item.posY).toInt, math.floor(item.posZ).toInt), 0) + world.levelEvent(2003, new BlockPos(math.floor(item.getX).toInt, math.floor(item.getY).toInt, math.floor(item.getZ).toInt), 0) return result(true) } } @@ -68,20 +68,20 @@ object UpgradeTractorBeam { } } - class Player(val owner: EnvironmentHost, val player: () => EntityPlayer) extends Common { + class Player(val owner: EnvironmentHost, val player: () => PlayerEntity) extends Common { override protected def position = BlockPosition(owner) - override protected def collectItem(item: EntityItem) = item.onCollideWithPlayer(player()) + override protected def collectItem(item: ItemEntity) = item.playerTouch(player()) } class Drone(val owner: internal.Agent) extends Common { override protected def position = BlockPosition(owner) - override protected def collectItem(item: EntityItem) = { + override protected def collectItem(item: ItemEntity) = { InventoryUtils.insertIntoInventory(item.getItem, owner.mainInventory, None, 64, simulate = false, Some(insertionSlots)) } - private def insertionSlots = (owner.selectedSlot until owner.mainInventory.getSizeInventory) ++ (0 until owner.selectedSlot) + private def insertionSlots = (owner.selectedSlot until owner.mainInventory.getContainerSize) ++ (0 until owner.selectedSlot) } } diff --git a/src/main/scala/li/cil/oc/server/component/UpgradeTrading.scala b/src/main/scala/li/cil/oc/server/component/UpgradeTrading.scala index f85de66f35..6b408d3b6d 100644 --- a/src/main/scala/li/cil/oc/server/component/UpgradeTrading.scala +++ b/src/main/scala/li/cil/oc/server/component/UpgradeTrading.scala @@ -18,11 +18,11 @@ import li.cil.oc.api.prefab import li.cil.oc.api.prefab.AbstractManagedEnvironment import li.cil.oc.util.BlockPosition import net.minecraft.entity.Entity -import net.minecraft.entity.IMerchant -import net.minecraft.util.math.Vec3d +import net.minecraft.entity.merchant.IMerchant +import net.minecraft.util.math.vector.Vector3d -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class UpgradeTrading(val host: EnvironmentHost) extends AbstractManagedEnvironment with traits.WorldAware with DeviceInfo { @@ -43,22 +43,22 @@ class UpgradeTrading(val host: EnvironmentHost) extends AbstractManagedEnvironme def maxRange = Settings.get.tradingRange - def isInRange(entity: Entity) = new Vec3d(entity.posX, entity.posY, entity.posZ).distanceTo(position.toVec3) <= maxRange + def isInRange(entity: Entity) = new Vector3d(entity.getX, entity.getY, entity.getZ).distanceTo(position.toVec3) <= maxRange @Callback(doc = "function():table -- Returns a table of trades in range as userdata objects.") def getTrades(context: Context, args: Arguments): Array[AnyRef] = { - val merchants = entitiesInBounds[Entity](classOf[Entity], position.bounds.grow(maxRange, maxRange, maxRange)). + val merchants = entitiesInBounds[Entity](classOf[Entity], position.bounds.inflate(maxRange, maxRange, maxRange)). filter(isInRange). - collect { case merchant: IMerchant => merchant } + collect { case merchant: Entity with IMerchant => merchant } var nextId = 1 val idMap = mutable.Map[UUID, Int]() - for (id: UUID <- merchants.collect { case merchant: IMerchant => merchant.getPersistentID }.sorted) { + for (id: UUID <- merchants.collect { case merchant: IMerchant => merchant.getUUID }.sorted) { idMap.put(id, nextId) nextId += 1 } // sorting the result is not necessary, but will help the merchant trades line up nicely by merchant - result(merchants.sortBy(m => m.getPersistentID).flatMap(merchant => merchant.getRecipes(null).indices.map(index => { - new Trade(this, merchant, index, idMap(merchant.getPersistentID)) + result(merchants.sortBy(m => m.getUUID).flatMap(merchant => merchant.getOffers.indices.map(index => { + new Trade(this, merchant, index, idMap(merchant.getUUID)) }))) } } diff --git a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala index 837ef6b684..7f73a763d9 100644 --- a/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala +++ b/src/main/scala/li/cil/oc/server/component/WirelessNetworkCard.scala @@ -17,9 +17,9 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.network._ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedWorld._ -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.language.implicitConversions abstract class WirelessNetworkCard(host: EnvironmentHost) extends NetworkCard(host) with WirelessEndpoint { @@ -100,7 +100,7 @@ abstract class WirelessNetworkCard(host: EnvironmentHost) extends NetworkCard(ho override def update() { super.update() - if (world.getTotalWorldTime % 20 == 0) { + if (world.getGameTime % 20 == 0) { api.Network.updateWirelessNetwork(this) } } @@ -114,7 +114,7 @@ abstract class WirelessNetworkCard(host: EnvironmentHost) extends NetworkCard(ho override def onDisconnect(node: Node) { super.onDisconnect(node) - if (node == this.node || !world.isBlockLoaded(position)) { + if (node == this.node || !world.isLoaded(position)) { api.Network.leaveWirelessNetwork(this) } } @@ -123,16 +123,16 @@ abstract class WirelessNetworkCard(host: EnvironmentHost) extends NetworkCard(ho private final val StrengthTag = "strength" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - if (nbt.hasKey(StrengthTag)) { + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + if (nbt.contains(StrengthTag)) { strength = nbt.getDouble(StrengthTag) max 0 min maxWirelessRange } } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setDouble(StrengthTag, strength) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putDouble(StrengthTag, strength) } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala index c8aae3d386..8c2ad15370 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala @@ -10,21 +10,22 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.StackOption._ import net.minecraft.item.ItemStack -import net.minecraftforge.oredict.OreDictionary + +import scala.collection.convert.ImplicitConversionsToScala._ trait InventoryAnalytics extends InventoryAware with NetworkAware { @Callback(doc = """function([slot:number]):table -- Get a description of the stack in the specified slot or the selected slot.""") def getStackInInternalSlot(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { val slot = optSlot(args, 0) - result(inventory.getStackInSlot(slot)) + result(inventory.getItem(slot)) } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") @Callback(doc = """function(otherSlot:number):boolean -- Get whether the stack in the selected slot is equivalent to the item in the specified slot (have shared OreDictionary IDs).""") def isEquivalentTo(context: Context, args: Arguments): Array[AnyRef] = { val slot = args.checkSlot(inventory, 0) result((stackInSlot(selectedSlot), stackInSlot(slot)) match { - case (SomeStack(stackA), SomeStack(stackB)) => OreDictionary.getOreIDs(stackA).intersect(OreDictionary.getOreIDs(stackB)).nonEmpty + case (SomeStack(stackA), SomeStack(stackB)) => stackA.getItem.getTags.intersect(stackB.getItem.getTags).nonEmpty case (EmptyStack, EmptyStack) => true case _ => false }) @@ -34,7 +35,7 @@ trait InventoryAnalytics extends InventoryAware with NetworkAware { def storeInternal(context: Context, args: Arguments): Array[AnyRef] = { val localSlot = args.checkSlot(inventory, 0) val dbAddress = args.checkString(1) - val localStack = inventory.getStackInSlot(localSlot) + val localStack = inventory.getItem(localSlot) DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 2) val nonEmpty = database.getStackInSlot(dbSlot) != ItemStack.EMPTY // zero size stacks! @@ -47,7 +48,7 @@ trait InventoryAnalytics extends InventoryAware with NetworkAware { def compareToDatabase(context: Context, args: Arguments): Array[AnyRef] = { val localSlot = args.checkSlot(inventory, 0) val dbAddress = args.checkString(1) - val localStack = inventory.getStackInSlot(localSlot) + val localStack = inventory.getItem(localSlot) DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 2) val dbStack = database.getStackInSlot(dbSlot) diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryAware.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryAware.scala index 37dc8a43d8..22235ac0ed 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryAware.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryAware.scala @@ -3,13 +3,13 @@ package li.cil.oc.server.component.traits import li.cil.oc.api.machine.Arguments import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.StackOption -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import scala.collection.immutable trait InventoryAware { - def fakePlayer: EntityPlayer + def fakePlayer: PlayerEntity def inventory: IInventory @@ -17,7 +17,7 @@ trait InventoryAware { def selectedSlot_=(value: Int): Unit - def insertionSlots: immutable.IndexedSeq[Int] = (selectedSlot until inventory.getSizeInventory) ++ (0 until selectedSlot) + def insertionSlots: immutable.IndexedSeq[Int] = (selectedSlot until inventory.getContainerSize) ++ (0 until selectedSlot) // ----------------------------------------------------------------------- // @@ -25,5 +25,5 @@ trait InventoryAware { if (args.count > 0 && args.checkAny(0) != null) args.checkSlot(inventory, 0) else selectedSlot - protected def stackInSlot(slot: Int): StackOption = StackOption(inventory.getStackInSlot(slot)) + protected def stackInSlot(slot: Int): StackOption = StackOption(inventory.getItem(slot)) } diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala index 3a083fbe00..57011f1819 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala @@ -11,7 +11,7 @@ import net.minecraft.item.ItemStack trait InventoryControl extends InventoryAware { @Callback(doc = "function():number -- The size of this device's internal inventory.") - def inventorySize(context: Context, args: Arguments): Array[AnyRef] = result(inventory.getSizeInventory) + def inventorySize(context: Context, args: Arguments): Array[AnyRef] = result(inventory.getContainerSize) @Callback(doc = "function([slot:number]):number -- Get the currently selected slot; set the selected slot if specified.") def select(context: Context, args: Arguments): Array[AnyRef] = { @@ -35,8 +35,8 @@ trait InventoryControl extends InventoryAware { def space(context: Context, args: Arguments): Array[AnyRef] = { val slot = optSlot(args, 0) result(stackInSlot(slot) match { - case SomeStack(stack) => math.min(inventory.getInventoryStackLimit, stack.getMaxStackSize) - stack.getCount - case _ => inventory.getInventoryStackLimit + case SomeStack(stack) => math.min(inventory.getMaxStackSize, stack.getMaxStackSize) - stack.getCount + case _ => inventory.getMaxStackSize }) } @@ -60,28 +60,28 @@ trait InventoryControl extends InventoryAware { else result((stackInSlot(selectedSlot), stackInSlot(slot)) match { case (SomeStack(from), SomeStack(to)) => if (InventoryUtils.haveSameItemType(from, to, checkNBT = true)) { - val space = math.min(inventory.getInventoryStackLimit, to.getMaxStackSize) - to.getCount + val space = math.min(inventory.getMaxStackSize, to.getMaxStackSize) - to.getCount val amount = math.min(count, math.min(space, from.getCount)) if (amount > 0) { from.shrink(amount) to.grow(amount) assert(from.getCount >= 0) if (from.getCount == 0) { - inventory.setInventorySlotContents(selectedSlot, ItemStack.EMPTY) + inventory.setItem(selectedSlot, ItemStack.EMPTY) } - inventory.markDirty() + inventory.setChanged() true } else false } else if (count >= from.getCount) { - inventory.setInventorySlotContents(slot, from) - inventory.setInventorySlotContents(selectedSlot, to) + inventory.setItem(slot, from) + inventory.setItem(selectedSlot, to) true } else false case (SomeStack(from), EmptyStack) => - inventory.setInventorySlotContents(slot, inventory.decrStackSize(selectedSlot, count)) + inventory.setItem(slot, inventory.removeItem(selectedSlot, count)) true case _ => false }) diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala index 594ada358c..b2fdf4ef60 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryTransfer.scala @@ -22,7 +22,7 @@ trait InventoryTransfer extends traits.WorldAware with traits.SideRestricted { onTransferContents() match { case Some(reason) => - result(Unit, reason) + result((), reason) case _ => val extractor = if (args.count > 3) { val sourceSlot = args.checkSlot(InventoryUtils.inventoryAt(sourcePos, sourceSide.getOpposite).getOrElse(throw new IllegalArgumentException("no inventory")), 3) @@ -35,7 +35,7 @@ trait InventoryTransfer extends traits.WorldAware with traits.SideRestricted { Option(extractor) match { case Some(ex) => result(ex()) - case _ => result(Unit, "no inventory") + case _ => result((), "no inventory") } } } @@ -50,7 +50,7 @@ trait InventoryTransfer extends traits.WorldAware with traits.SideRestricted { onTransferContents() match { case Some(reason) => - result(Unit, reason) + result((), reason) case _ => val moved = FluidUtils.transferBetweenFluidHandlersAt(sourcePos, sourceSide.getOpposite, sinkPos, sinkSide.getOpposite, count) if (moved > 0) context.pause(moved / 1000 * 0.25) // Allow up to 4 buckets per second. diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala index 28efa67168..18120e5878 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala @@ -8,28 +8,28 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.ResultWrapper.result import li.cil.oc.util.StackOption._ -import net.minecraft.entity.item.EntityItem -import net.minecraft.item.ItemBlock +import net.minecraft.entity.item.ItemEntity +import net.minecraft.item.BlockItem import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraftforge.common.MinecraftForge import net.minecraftforge.event.entity.item.ItemTossEvent -import net.minecraftforge.fml.common.eventhandler.Event.Result +import net.minecraftforge.eventbus.api.Event.Result -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRestricted { - @Callback(doc = "function(side:number[, fuzzy:boolean=false]):boolean -- Compare the block on the specified side with the one in the selected slot. Returns true if equal.") + @Callback(doc = "function(side:number):boolean -- Compare the block on the specified side with the one in the selected slot. Returns true if equal.") def compare(context: Context, args: Arguments): Array[AnyRef] = { val side = checkSideForAction(args, 0) stackInSlot(selectedSlot) match { case SomeStack(stack) => Option(stack.getItem) match { - case Some(item: ItemBlock) => + case Some(item: BlockItem) => val blockPos = position.offset(side).toBlockPos val state = world.getBlockState(blockPos) val idMatches = item.getBlock == state.getBlock - val subTypeMatches = args.optBoolean(1, false) || !item.getHasSubtypes || item.getMetadata(stack.getItemDamage) == state.getBlock.getMetaFromState(state) - return result(idMatches && subTypeMatches) + args.optBoolean(1, false) // TODO + return result(idMatches) case _ => } case _ => @@ -41,7 +41,7 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest def drop(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) val count = args.optItemCount(1) - val stack = inventory.getStackInSlot(selectedSlot) + val stack = inventory.getItem(selectedSlot) if (!stack.isEmpty && stack.getCount > 0) { val blockPos = position.offset(facing) InventoryUtils.inventoryAt(blockPos, facing.getOpposite) match { @@ -52,16 +52,16 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest } else if (stack.getCount == 0) { // Dropped whole stack. - inventory.setInventorySlotContents(selectedSlot, ItemStack.EMPTY) + inventory.setItem(selectedSlot, ItemStack.EMPTY) } else { // Dropped partial stack. - inventory.markDirty() + inventory.setChanged() } case _ => // No inventory to drop into, drop into the world. - val dropped = inventory.decrStackSize(selectedSlot, count) - val validator = (item: EntityItem) => { + val dropped = inventory.removeItem(selectedSlot, count) + val validator = (item: ItemEntity) => { val event = new ItemTossEvent(item, fakePlayer) val canceled = MinecraftForge.EVENT_BUS.post(event) val denied = event.hasResult && event.getResult == Result.DENY @@ -69,7 +69,7 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest } if (!dropped.isEmpty) { if (InventoryUtils.spawnStackInWorld(position, dropped, Some(facing), Some(validator)) == null) - fakePlayer.inventory.addItemStackToInventory(dropped) + fakePlayer.inventory.add(dropped) } } @@ -84,14 +84,14 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest * @param facing items to suck from * @return the number of items sucked */ - def suckFromItems(facing: EnumFacing): Int = { - for (entity <- suckableItems(facing) if !entity.isDead && !entity.cannotPickup) { + def suckFromItems(facing: Direction): Int = { + for (entity <- suckableItems(facing) if entity.isAlive && !entity.hasPickUpDelay) { val stack = entity.getItem val size = stack.getCount onSuckCollect(entity) if (stack.getCount < size) return size - stack.getCount - else if (entity.isDead) + else if (!entity.isAlive) return size } 0 @@ -119,7 +119,7 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest } } - protected def suckableItems(side: EnumFacing) = entitiesOnSide(classOf[EntityItem], side) + protected def suckableItems(side: Direction) = entitiesOnSide(classOf[ItemEntity], side) - protected def onSuckCollect(entity: EntityItem): Unit = entity.onCollideWithPlayer(fakePlayer) + protected def onSuckCollect(entity: ItemEntity): Unit = entity.playerTouch(fakePlayer) } diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala index 60914b32fb..96aad1ee46 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala @@ -9,7 +9,7 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.InventoryUtils import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraftforge.items.IItemHandler trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideRestricted { @@ -18,7 +18,7 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR val facing = checkSideForAction(args, 0) val count = args.optItemCount(2) val fromSide = args.optSideAny(3, facing.getOpposite) - val stack = inventory.getStackInSlot(selectedSlot) + val stack = inventory.getItem(selectedSlot) if (!stack.isEmpty && stack.getCount > 0) { withInventory(position.offset(facing), fromSide, inventory => { val slot = args.checkSlot(inventory, 1) @@ -28,11 +28,11 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR } else if (stack.getCount == 0) { // Dropped whole stack. - this.inventory.setInventorySlotContents(selectedSlot, ItemStack.EMPTY) + this.inventory.setItem(selectedSlot, ItemStack.EMPTY) } else { // Dropped partial stack. - this.inventory.markDirty() + this.inventory.setChanged() } context.pause(Settings.get.dropDelay) @@ -59,9 +59,9 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR }) } - private def withInventory(blockPos: BlockPosition, fromSide: EnumFacing, f: IItemHandler => Array[AnyRef]) = + private def withInventory(blockPos: BlockPosition, fromSide: Direction, f: IItemHandler => Array[AnyRef]) = InventoryUtils.inventoryAt(blockPos, fromSide) match { case Some(inventory) if mayInteract(blockPos, fromSide) => f(inventory) - case _ => result(Unit, "no inventory") + case _ => result((), "no inventory") } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala index 42026cd360..172e51e05e 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala @@ -35,7 +35,7 @@ trait ItemInventoryControl extends InventoryAware { } private def withItemInventory(slot: Int, f: IItemHandler => Array[AnyRef]): Array[AnyRef] = { - inventory.getStackInSlot(slot) match { + inventory.getItem(slot) match { case stack: ItemStack => api.Driver.itemHandlerFor(stack, fakePlayer) match { case inventory: IItemHandler => f(inventory) case _ => result(0, "no item inventory") diff --git a/src/main/scala/li/cil/oc/server/component/traits/SideRestricted.scala b/src/main/scala/li/cil/oc/server/component/traits/SideRestricted.scala index 1201e35221..5cc79c7cd7 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/SideRestricted.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/SideRestricted.scala @@ -1,8 +1,8 @@ package li.cil.oc.server.component.traits import li.cil.oc.api.machine.Arguments -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction trait SideRestricted { - protected def checkSideForAction(args: Arguments, n: Int): EnumFacing + protected def checkSideForAction(args: Arguments, n: Int): Direction } diff --git a/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala b/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala index 33815f2e94..adc040d715 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/TankControl.scala @@ -5,6 +5,7 @@ import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ResultWrapper.result +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction trait TankControl extends TankAware { @Callback(doc = "function():number -- The number of tanks installed in the device.") @@ -24,7 +25,7 @@ trait TankControl extends TankAware { if (args.count > 0 && args.checkAny(0) != null) args.checkTank(tank, 0) else selectedTank result(fluidInTank(index) match { - case Some(fluid) => fluid.amount + case Some(fluid) => fluid.getAmount case _ => 0 }) } @@ -59,21 +60,21 @@ trait TankControl extends TankAware { } else (getTank(selectedTank), getTank(index)) match { case (Some(from), Some(to)) => - val drained = from.drain(count, false) - val transferred = to.fill(drained, true) + val drained = from.drain(count, FluidAction.SIMULATE) + val transferred = to.fill(drained, FluidAction.EXECUTE) if (transferred > 0) { - from.drain(transferred, true) + from.drain(transferred, FluidAction.EXECUTE) result(true) } else if (count >= from.getFluidAmount && to.getCapacity >= from.getFluidAmount && from.getCapacity >= to.getFluidAmount) { // Swap. - val tmp = to.drain(to.getFluidAmount, true) - to.fill(from.drain(from.getFluidAmount, true), true) - from.fill(tmp, true) + val tmp = to.drain(to.getFluidAmount, FluidAction.EXECUTE) + to.fill(from.drain(from.getFluidAmount, FluidAction.EXECUTE), FluidAction.EXECUTE) + from.fill(tmp, FluidAction.EXECUTE) result(true) } - else result(Unit, "incompatible or no fluid") - case _ => result(Unit, "invalid index") + else result((), "incompatible or no fluid") + case _ => result((), "invalid index") } } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala index 96571deea0..326f712cfc 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/TankInventoryControl.scala @@ -10,11 +10,13 @@ import li.cil.oc.util.FluidUtils import li.cil.oc.util.InventoryUtils import net.minecraft.item.ItemStack import net.minecraftforge.fluids.FluidStack +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction +import net.minecraftforge.fluids.capability.CapabilityFluidHandler trait TankInventoryControl extends WorldAware with InventoryAware with TankAware { @Callback(doc = """function([slot:number]):number -- Get the amount of fluid in the tank item in the specified slot or the selected slot.""") def getTankLevelInSlot(context: Context, args: Arguments): Array[AnyRef] = - withFluidInfo(optSlot(args, 0), (fluid, _) => result(fluid.fold(0)(_.amount))) + withFluidInfo(optSlot(args, 0), (fluid, _) => result(fluid.fold(0)(_.getAmount))) @Callback(doc = """function([slot:number]):number -- Get the capacity of the tank item in the specified slot of the robot or the selected slot.""") def getTankCapacityInSlot(context: Context, args: Arguments): Array[AnyRef] = @@ -24,35 +26,35 @@ trait TankInventoryControl extends WorldAware with InventoryAware with TankAware def getFluidInTankInSlot(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { withFluidInfo(optSlot(args, 0), (fluid, _) => result(fluid.orNull)) } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") @Callback(doc = """function([tank:number]):table -- Get a description of the fluid in the tank in the specified slot or the selected slot.""") def getFluidInInternalTank(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { result(Option(tank.getFluidTank(optTank(args, 0))).map(_.getFluid).orNull) } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") @Callback(doc = """function([amount:number]):boolean -- Transfers fluid from a tank in the selected inventory slot to the selected tank.""") def drain(context: Context, args: Arguments): Array[AnyRef] = { val amount = args.optFluidCount(0) Option(tank.getFluidTank(selectedTank)) match { - case Some(into) => inventory.getStackInSlot(selectedSlot) match { + case Some(into) => inventory.getItem(selectedSlot) match { case stack: ItemStack => Option(FluidUtils.fluidHandlerOf(stack)) match { case Some(handler) => - val drained = handler.drain(amount, false) - val transferred = into.fill(drained, true) + val drained = handler.drain(amount, FluidAction.SIMULATE) + val transferred = into.fill(drained, FluidAction.EXECUTE) if (transferred > 0) { - handler.drain(transferred, true) - inventory.setInventorySlotContents(selectedSlot, handler.getContainer) + handler.drain(transferred, FluidAction.EXECUTE) + inventory.setItem(selectedSlot, handler.getContainer) result(true, transferred) } - else result(Unit, "incompatible or no fluid") - case _ => result(Unit, "item is not a fluid container") + else result((), "incompatible or no fluid") + case _ => result((), "item is not a fluid container") } - case _ => result(Unit, "nothing selected") + case _ => result((), "nothing selected") } - case _ => result(Unit, "no tank") + case _ => result((), "no tank") } } @@ -60,38 +62,37 @@ trait TankInventoryControl extends WorldAware with InventoryAware with TankAware def fill(context: Context, args: Arguments): Array[AnyRef] = { val amount = args.optFluidCount(0) Option(tank.getFluidTank(selectedTank)) match { - case Some(from) => inventory.getStackInSlot(selectedSlot) match { + case Some(from) => inventory.getItem(selectedSlot) match { case stack: ItemStack => Option(FluidUtils.fluidHandlerOf(stack)) match { case Some(handler) => - val drained = from.drain(amount, false) - val transferred = handler.fill(drained, true) + val drained = from.drain(amount, FluidAction.SIMULATE) + val transferred = handler.fill(drained, FluidAction.EXECUTE) if (transferred > 0) { - from.drain(transferred, true) - inventory.setInventorySlotContents(selectedSlot, handler.getContainer) + from.drain(transferred, FluidAction.EXECUTE) + inventory.setItem(selectedSlot, handler.getContainer) result(true, transferred) } - else result(Unit, "incompatible or no fluid") - case _ => result(Unit, "item is not a fluid container") + else result((), "incompatible or no fluid") + case _ => result((), "item is not a fluid container") } - case _ => result(Unit, "nothing selected") + case _ => result((), "nothing selected") } - case _ => result(Unit, "no tank") + case _ => result((), "no tank") } } private def withFluidInfo(slot: Int, f: (Option[FluidStack], Int) => Array[AnyRef]) = { def fluidInfo(stack: ItemStack) = Option(FluidUtils.fluidHandlerOf(stack)) match { - case Some(handler) if handler.getTankProperties.length > 0 => - val props = handler.getTankProperties()(0) - Option((Option(props.getContents), props.getCapacity)) + case Some(handler) if handler.getTanks > 0 => + Option((Option(handler.getFluidInTank(0)), handler.getTankCapacity(0))) case _ => None } - inventory.getStackInSlot(slot) match { + inventory.getItem(slot) match { case stack: ItemStack => fluidInfo(stack) match { case Some((fluid, capacity)) => f(fluid, capacity) - case _ => result(Unit, "item is not a fluid container") + case _ => result((), "item is not a fluid container") } } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala b/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala index 521eab40ca..3016d9f6c0 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/TankWorldControl.scala @@ -7,7 +7,7 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.FluidUtils import li.cil.oc.util.ResultWrapper.result import net.minecraftforge.fluids.FluidStack -import net.minecraftforge.fluids.capability.IFluidTankProperties +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction trait TankWorldControl extends TankAware with WorldAware with SideRestricted { @Callback(doc = "function(side:number [, tank:number]):boolean -- Compare the fluid in the selected tank with the fluid in the specified tank on the specified side. Returns true if equal.") @@ -17,8 +17,8 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { case Some(stack) => FluidUtils.fluidHandlerAt(position.offset(side), side.getOpposite) match { case Some(handler) => args.optTankProperties(handler, 1, null) match { - case properties: IFluidTankProperties => result(stack.isFluidEqual(properties.getContents)) - case _ => result(Option(handler.getTankProperties).exists(_.exists(other => stack.isFluidEqual(other.getContents)))) + case properties: TankProperties => result(stack.isFluidEqual(properties.contents)) + case _ => result((0 until handler.getTanks).map(handler.getFluidInTank).exists(stack.isFluidEqual)) } case _ => result(false) } @@ -39,21 +39,21 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { case Some(handler) => tank.getFluid match { case stack: FluidStack => - val drained = handler.drain(new FluidStack(stack, amount), true) - if ((drained != null && drained.amount > 0) || amount == 0) { - val filled = tank.fill(drained, true) + val drained = handler.drain(new FluidStack(stack, amount), FluidAction.EXECUTE) + if ((drained != null && drained.getAmount > 0) || amount == 0) { + val filled = tank.fill(drained, FluidAction.EXECUTE) result(true, filled) } - else result(Unit, "incompatible or no fluid") + else result((), "incompatible or no fluid") case _ => - val transferred = tank.fill(handler.drain(amount, true), true) + val transferred = tank.fill(handler.drain(amount, FluidAction.EXECUTE), FluidAction.EXECUTE) result(transferred > 0, transferred) } - case _ => result(Unit, "incompatible or no fluid") + case _ => result((), "incompatible or no fluid") } } - else result(Unit, "tank is full") - case _ => result(Unit, "no tank selected") + else result((), "tank is full") + case _ => result((), "no tank selected") } } @@ -69,20 +69,20 @@ trait TankWorldControl extends TankAware with WorldAware with SideRestricted { case Some(handler) => tank.getFluid match { case stack: FluidStack => - val filled = handler.fill(new FluidStack(stack, amount), true) + val filled = handler.fill(new FluidStack(stack, amount), FluidAction.EXECUTE) if (filled > 0 || amount == 0) { - tank.drain(filled, true) + tank.drain(filled, FluidAction.EXECUTE) result(true, filled) } - else result(Unit, "incompatible or no fluid") + else result((), "incompatible or no fluid") case _ => - result(Unit, "tank is empty") + result((), "tank is empty") } - case _ => result(Unit, "no space") + case _ => result((), "no space") } } - else result(Unit, "tank is empty") - case _ => result(Unit, "no tank selected") + else result((), "tank is empty") + case _ => result((), "no tank selected") } } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/WakeMessageAware.scala b/src/main/scala/li/cil/oc/server/component/traits/WakeMessageAware.scala index fe1255c8a1..40a2a87402 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WakeMessageAware.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WakeMessageAware.scala @@ -6,7 +6,7 @@ import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.api.network.{EnvironmentHost, Packet} import li.cil.oc.server.component._ -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT trait WakeMessageAware extends traits.NetworkAware { private final val WakeMessageTag = "wakeMessage" @@ -60,15 +60,15 @@ trait WakeMessageAware extends traits.NetworkAware { } } - def loadWakeMessage(nbt: NBTTagCompound): Unit = { - if (nbt.hasKey(WakeMessageTag)) { + def loadWakeMessage(nbt: CompoundNBT): Unit = { + if (nbt.contains(WakeMessageTag)) { wakeMessage = Option(nbt.getString(WakeMessageTag)) } wakeMessageFuzzy = nbt.getBoolean(WakeMessageFuzzyTag) } - def saveWakeMessage(nbt: NBTTagCompound): Unit = { - wakeMessage.foreach(nbt.setString(WakeMessageTag, _)) - nbt.setBoolean(WakeMessageFuzzyTag, wakeMessageFuzzy) + def saveWakeMessage(nbt: CompoundNBT): Unit = { + wakeMessage.foreach(nbt.putString(WakeMessageTag, _)) + nbt.putBoolean(WakeMessageFuzzyTag, wakeMessageFuzzy) } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala index eaf94a5f47..422e295fcb 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldAware.scala @@ -6,38 +6,41 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedBlock._ import li.cil.oc.util.ExtendedWorld._ import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.item.EntityMinecart -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.util.EnumFacing -import net.minecraft.util.EnumHand +import net.minecraft.entity.LivingEntity +import net.minecraft.entity.item.minecart.MinecartEntity +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.util.Direction +import net.minecraft.util.Hand import net.minecraft.util.math.AxisAlignedBB -import net.minecraft.world.WorldServer +import net.minecraft.util.math.BlockRayTraceResult +import net.minecraft.util.math.shapes.ISelectionContext +import net.minecraft.world.server.ServerWorld import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.util.FakePlayerFactory import net.minecraftforge.event.entity.player.PlayerInteractEvent import net.minecraftforge.event.world.BlockEvent -import net.minecraftforge.fluids.FluidRegistry -import net.minecraftforge.fml.common.eventhandler.Event.Result +import net.minecraftforge.eventbus.api.Event.Result +import net.minecraftforge.fluids.IFluidBlock import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.wrapper.InvWrapper +import scala.collection.convert.ImplicitConversionsToScala._ + trait WorldAware { def position: BlockPosition def world = position.world.get - def fakePlayer: EntityPlayer = { - val player = FakePlayerFactory.get(world.asInstanceOf[WorldServer], Settings.get.fakePlayerProfile) - player.posX = position.x + 0.5 - player.posY = position.y + 0.5 - player.posZ = position.z + 0.5 + def fakePlayer: PlayerEntity = { + val player = FakePlayerFactory.get(world.asInstanceOf[ServerWorld], Settings.get.fakePlayerProfile) + player.setPos(position.x + 0.5, position.y + 0.5, position.z + 0.5) player } - def mayInteract(blockPos: BlockPosition, face: EnumFacing): Boolean = { + def mayInteract(blockPos: BlockPosition, face: Direction): Boolean = { try { - val event = new PlayerInteractEvent.RightClickBlock(fakePlayer, EnumHand.MAIN_HAND, blockPos.toBlockPos, face, null) + val trace = new BlockRayTraceResult(fakePlayer.position, face, blockPos.toBlockPos, false) + val event = new PlayerInteractEvent.RightClickBlock(fakePlayer, Hand.MAIN_HAND, blockPos.toBlockPos, trace) MinecraftForge.EVENT_BUS.post(event) !event.isCanceled && event.getUseBlock != Result.DENY } catch { @@ -47,50 +50,51 @@ trait WorldAware { } } - def mayInteract(blockPos: BlockPosition, side: EnumFacing, inventory: IItemHandler): Boolean = mayInteract(blockPos, side) && (inventory match { - case inv: InvWrapper if inv.getInv != null => inv.getInv.isUsableByPlayer(fakePlayer) + def mayInteract(blockPos: BlockPosition, side: Direction, inventory: IItemHandler): Boolean = mayInteract(blockPos, side) && (inventory match { + case inv: InvWrapper if inv.getInv != null => inv.getInv.stillValid(fakePlayer) case _ => true }) def entitiesInBounds[Type <: Entity](clazz: Class[Type], bounds: AxisAlignedBB) = { - world.getEntitiesWithinAABB(clazz, bounds) + world.getEntitiesOfClass(clazz, bounds) } def entitiesInBlock[Type <: Entity](clazz: Class[Type], blockPos: BlockPosition) = { entitiesInBounds(clazz, blockPos.bounds) } - def entitiesOnSide[Type <: Entity](clazz: Class[Type], side: EnumFacing) = { + def entitiesOnSide[Type <: Entity](clazz: Class[Type], side: Direction) = { entitiesInBlock(clazz, position.offset(side)) } - def closestEntity[Type <: Entity](clazz: Class[Type], side: EnumFacing) = { + def closestEntity[Type <: Entity](clazz: Class[Type], side: Direction) = { val blockPos = position.offset(side) - Option(world.findNearestEntityWithinAABB(clazz, blockPos.bounds, fakePlayer)) + val candidates = world.getEntitiesOfClass(clazz, blockPos.bounds, null) + if (!candidates.isEmpty) Some(candidates.minBy(e => fakePlayer.distanceToSqr(e))) else None } - def blockContent(side: EnumFacing) = { + def blockContent(side: Direction) = { closestEntity[Entity](classOf[Entity], side) match { - case Some(_@(_: EntityLivingBase | _: EntityMinecart)) => + case Some(_@(_: LivingEntity | _: MinecartEntity)) => (true, "entity") case _ => val blockPos = position.offset(side) - val block = world.getBlock(blockPos) - val metadata = world.getBlockMetadata(blockPos) - if (block.isAir(blockPos)) { + val state = world.getBlockState(blockPos.toBlockPos) + val block = state.getBlock + if (block.isAir(state, world, blockPos.toBlockPos)) { (false, "air") } - else if (FluidRegistry.lookupFluidForBlock(block) != null) { - val event = new BlockEvent.BreakEvent(world, blockPos.toBlockPos, metadata, fakePlayer) + else if (!block.isInstanceOf[IFluidBlock]) { + val event = new BlockEvent.BreakEvent(world, blockPos.toBlockPos, state, fakePlayer) MinecraftForge.EVENT_BUS.post(event) (event.isCanceled, "liquid") } else if (block.isReplaceable(blockPos)) { - val event = new BlockEvent.BreakEvent(world, blockPos.toBlockPos, metadata, fakePlayer) + val event = new BlockEvent.BreakEvent(world, blockPos.toBlockPos, state, fakePlayer) MinecraftForge.EVENT_BUS.post(event) (event.isCanceled, "replaceable") } - else if (block.getCollisionBoundingBoxFromPool(blockPos) == null) { + else if (state.getCollisionShape(world, blockPos.toBlockPos, ISelectionContext.empty).isEmpty) { (true, "passable") } else { diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala index ee46da2f1c..7714e2b8e2 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala @@ -12,9 +12,10 @@ import li.cil.oc.util.ExtendedArguments._ import net.minecraft.block.Block import li.cil.oc.util.StackOption import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraftforge.items.IItemHandler -import net.minecraftforge.oredict.OreDictionary + +import scala.collection.convert.ImplicitConversionsToScala._ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with NetworkAware { @Callback(doc = """function(side:number):number -- Get the number of slots in the inventory on the specified side of the device.""") @@ -68,16 +69,16 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ val stackB = inventory.getStackInSlot(args.checkSlot(inventory, 2)) result(stackA == stackB || (!stackA.isEmpty && !stackB.isEmpty && - OreDictionary.getOreIDs(stackA).intersect(OreDictionary.getOreIDs(stackB)).nonEmpty)) + stackA.getItem.getTags.intersect(stackB.getItem.getTags).nonEmpty)) }) } @Callback(doc = """function(side:number, slot:number):table -- Get a description of the stack in the inventory on the specified side of the device.""") - def getStackInSlot(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { + def getItem(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { val facing = checkSideForAction(args, 0) withInventory(facing, inventory => result(inventory.getStackInSlot(args.checkSlot(inventory, 1)))) } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") @Callback(doc = """function(side:number):userdata -- Get a description of all stacks in the inventory on the specified side of the device.""") def getAllStacks(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { @@ -90,7 +91,7 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ result(new ItemStackArrayValue(stacks)) }) } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") @Callback(doc = """function(side:number):string -- Get the the name of the inventory on the specified side of the device.""") def getInventoryName(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { @@ -104,10 +105,10 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ } withInventory(facing, inventory => blockAt(position.offset(facing)) match { case Some(block) => result(block.getRegistryName) - case _ => result(Unit, "Unknown") + case _ => result((), "Unknown") }) } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") @Callback(doc = """function(side:number, slot:number, dbAddress:string, dbSlot:number):boolean -- Store an item stack description in the specified slot of the database with the specified address.""") def store(context: Context, args: Arguments): Array[AnyRef] = { @@ -122,9 +123,9 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ withInventory(facing, inventory => store(inventory.getStackInSlot(args.checkSlot(inventory, 1)))) } - private def withInventory(side: EnumFacing, f: IItemHandler => Array[AnyRef]) = + private def withInventory(side: Direction, f: IItemHandler => Array[AnyRef]) = InventoryUtils.inventoryAt(position.offset(side), side.getOpposite) match { case Some(inventory) if mayInteract(position.offset(side), side.getOpposite, inventory) => f(inventory) - case _ => result(Unit, "no inventory") + case _ => result((), "no inventory") } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala index e2edd63b8e..89133115c5 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldTankAnalytics.scala @@ -7,7 +7,6 @@ import li.cil.oc.api.machine.Context import li.cil.oc.server.component.result import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.FluidUtils -import net.minecraftforge.fluids.capability.IFluidTankProperties trait WorldTankAnalytics extends WorldAware with SideRestricted { @Callback(doc = """function(side:number [, tank:number]):number -- Get the amount of fluid in the tank on the specified side.""") @@ -16,10 +15,10 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted { FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => args.optTankProperties(handler, 1, null) match { - case properties: IFluidTankProperties => result(Option(properties.getContents).fold(0)(_.amount)) - case _ => result(handler.getTankProperties.map(info => Option(info.getContents).fold(0)(_.amount)).sum) + case properties: TankProperties => result(Option(properties.contents).fold(0)(_.getAmount)) + case _ => result((0 until handler.getTanks).map(i => Option(handler.getFluidInTank(i)).fold(0)(_.getAmount)).sum) } - case _ => result(Unit, "no tank") + case _ => result((), "no tank") } } @@ -28,10 +27,10 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted { val facing = checkSideForAction(args, 0) FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => args.optTankProperties(handler, 1, null) match { - case properties: IFluidTankProperties => result(properties.getCapacity) - case _ => result(handler.getTankProperties.map(_.getCapacity).foldLeft(0)((max, capacity) => math.max(max, capacity))) + case properties: TankProperties => result(properties.capacity) + case _ => result((0 until handler.getTanks).map(handler.getTankCapacity).foldLeft(0)((max, capacity) => math.max(max, capacity))) } - case _ => result(Unit, "no tank") + case _ => result((), "no tank") } } @@ -40,11 +39,11 @@ trait WorldTankAnalytics extends WorldAware with SideRestricted { val facing = checkSideForAction(args, 0) FluidUtils.fluidHandlerAt(position.offset(facing), facing.getOpposite) match { case Some(handler) => args.optTankProperties(handler, 1, null) match { - case properties: IFluidTankProperties => result(properties) - case _ => result(handler.getTankProperties) + case properties: TankProperties => result(properties) + case _ => result((0 until handler.getTanks).map(i => new TankProperties(handler.getTankCapacity(i), handler.getFluidInTank(i))).toArray) } - case _ => result(Unit, "no tank") + case _ => result((), "no tank") } } - else result(Unit, "not enabled in config") + else result((), "not enabled in config") } diff --git a/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala b/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala index b7be2887c7..fe7c0fe68f 100644 --- a/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala +++ b/src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala @@ -9,12 +9,12 @@ import net.minecraft.inventory.IInventory import net.minecraft.item.Item import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World class CompoundBlockDriver(val sidedBlocks: Array[DriverBlock]) extends DriverBlock { - override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): CompoundBlockEnvironment = { + override def createEnvironment(world: World, pos: BlockPos, side: Direction): CompoundBlockEnvironment = { val list = sidedBlocks.map { driver => Option(driver.createEnvironment(world, pos, side)) match { case Some(environment) => (driver.getClass.getName, environment) @@ -25,7 +25,7 @@ class CompoundBlockDriver(val sidedBlocks: Array[DriverBlock]) extends DriverBlo else new CompoundBlockEnvironment(cleanName(tryGetName(world, pos, list.map(_._2))), list: _*) } - override def worksWith(world: World, pos: BlockPos, side: EnumFacing): Boolean = sidedBlocks.forall(_.worksWith(world, pos, side)) + override def worksWith(world: World, pos: BlockPos, side: Direction): Boolean = sidedBlocks.forall(_.worksWith(world, pos, side)) override def equals(obj: Any): Boolean = obj match { case multi: CompoundBlockDriver if multi.sidedBlocks.length == sidedBlocks.length => sidedBlocks.intersect(multi.sidedBlocks).length == sidedBlocks.length @@ -40,26 +40,21 @@ class CompoundBlockDriver(val sidedBlocks: Array[DriverBlock]) extends DriverBlo case Some(named) => return named.preferredName case _ => // No preferred name. } - try world.getTileEntity(pos) match { - case inventory: IInventory if !Strings.isNullOrEmpty(inventory.getName) => return inventory.getName.stripPrefix("container.") - } catch { - case _: Throwable => - } try { val block = world.getBlockState(pos).getBlock - val stack = if (Item.getItemFromBlock(block) != null) { - Some(new ItemStack(block, 1, block.damageDropped(world.getBlockState(pos)))) + val stack = if (block.asItem() != null) { + Some(new ItemStack(block, 1)) } else None if (stack.isDefined) { - return stack.get.getUnlocalizedName.stripPrefix("tile.") + return stack.get.getDescriptionId.stripPrefix("tile.") } } catch { case _: Throwable => } - try world.getTileEntity(pos) match { + try world.getBlockEntity(pos) match { case tileEntity: TileEntity => - return TileEntity.getKey(tileEntity.getClass).getResourcePath + return tileEntity.getType.getRegistryName.getPath } catch { case _: Throwable => } diff --git a/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala b/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala index 10ea6510c1..41ea4b17e7 100644 --- a/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala +++ b/src/main/scala/li/cil/oc/server/driver/CompoundBlockEnvironment.scala @@ -7,7 +7,7 @@ import li.cil.oc.OpenComputers import li.cil.oc.api import li.cil.oc.api.network._ import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT class CompoundBlockEnvironment(val name: String, val environments: (String, ManagedEnvironment)*) extends ManagedEnvironment { // Block drivers with visibility < network usually won't make much sense, @@ -54,14 +54,14 @@ class CompoundBlockEnvironment(val name: String, val environments: (String, Mana private final val TypeHashTag = "typeHash" - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { // Ignore existing data if the underlying type is different. - if (nbt.hasKey(TypeHashTag) && nbt.getLong(TypeHashTag) != typeHash) return - node.load(nbt) + if (nbt.contains(TypeHashTag) && nbt.getLong(TypeHashTag) != typeHash) return + node.loadData(nbt) for ((driver, environment) <- environments) { - if (nbt.hasKey(driver)) { + if (nbt.contains(driver)) { try { - environment.load(nbt.getCompoundTag(driver)) + environment.loadData(nbt.getCompound(driver)) } catch { case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while loading.", e) } @@ -69,12 +69,12 @@ class CompoundBlockEnvironment(val name: String, val environments: (String, Mana } } - override def save(nbt: NBTTagCompound) { - nbt.setLong(TypeHashTag, typeHash) - node.save(nbt) + override def saveData(nbt: CompoundNBT) { + nbt.putLong(TypeHashTag, typeHash) + node.saveData(nbt) for ((driver, environment) <- environments) { try { - nbt.setNewCompoundTag(driver, environment.save) + nbt.setNewCompoundTag(driver, environment.saveData) } catch { case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while saving.", e) } diff --git a/src/main/scala/li/cil/oc/server/driver/Registry.scala b/src/main/scala/li/cil/oc/server/driver/Registry.scala index 4a8e21c4bc..b098c76537 100644 --- a/src/main/scala/li/cil/oc/server/driver/Registry.scala +++ b/src/main/scala/li/cil/oc/server/driver/Registry.scala @@ -13,17 +13,18 @@ import li.cil.oc.api.driver.item.HostAware import li.cil.oc.api.machine.Value import li.cil.oc.api.network.EnvironmentHost import li.cil.oc.util.InventoryUtils -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.item.ItemStack -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos import net.minecraft.world.World import net.minecraftforge.items.CapabilityItemHandler import net.minecraftforge.items.IItemHandler -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.mapAsScalaMap +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable import scala.collection.mutable.ArrayBuffer import scala.math.ScalaNumber @@ -98,7 +99,7 @@ private[oc] object Registry extends api.detail.DriverAPI { } } - override def driverFor(world: World, pos: BlockPos, side: EnumFacing): DriverBlock = + override def driverFor(world: World, pos: BlockPos, side: Direction): DriverBlock = sidedBlocks.filter(_.worksWith(world, pos, side)) match { case sidedDrivers if sidedDrivers.nonEmpty => new CompoundBlockDriver(sidedDrivers.toArray) case _ => null @@ -129,20 +130,18 @@ private[oc] object Registry extends api.detail.DriverAPI { override def environmentsFor(stack: ItemStack): util.Set[Class[_]] = environmentProviders.map(_.getEnvironment(stack)).filter(_ != null).toSet[Class[_]] - override def itemHandlerFor(stack: ItemStack, player: EntityPlayer): IItemHandler = { + override def itemHandlerFor(stack: ItemStack, player: PlayerEntity): IItemHandler = { inventoryProviders.find(provider => provider.worksWith(stack, player)). map(provider => InventoryUtils.asItemHandler(provider.getInventory(stack, player))). getOrElse { - if(stack.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null)) - stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null) - else null + stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).orElse(null) } } override def itemDrivers: util.List[DriverItem] = items.toSeq def blacklistHost(stack: ItemStack, host: Class[_]) { - blacklist.find(_._1.isItemEqual(stack)) match { + blacklist.find(_._1.sameItem(stack)) match { case Some((_, hosts)) => hosts += host case _ => blacklist.append((stack, mutable.Set(host))) } @@ -150,7 +149,7 @@ private[oc] object Registry extends api.detail.DriverAPI { def convert(value: Array[AnyRef]): Array[AnyRef] = if (value != null) value.map(arg => convertRecursively(arg, new util.IdentityHashMap())) else null - def convertRecursively(value: Any, memo: util.IdentityHashMap[AnyRef, AnyRef], force: Boolean = false): AnyRef = { + def convertRecursively(value: Any, memo: util.IdentityHashMap[Any, AnyRef], force: Boolean = false): AnyRef = { val valueRef = value match { case number: ScalaNumber => number.underlying case reference: AnyRef => reference @@ -161,7 +160,7 @@ private[oc] object Registry extends api.detail.DriverAPI { memo.get(valueRef) } else valueRef match { - case null | Unit | None => null + case null | () | None => null case arg: java.lang.Boolean => arg case arg: java.lang.Byte => arg @@ -231,7 +230,7 @@ private[oc] object Registry extends api.detail.DriverAPI { } } - def convertList(obj: AnyRef, list: Iterator[(Any, Int)], memo: util.IdentityHashMap[AnyRef, AnyRef]): Array[AnyRef] = { + def convertList(obj: Any, list: Iterator[(Any, Int)], memo: util.IdentityHashMap[Any, AnyRef]): Array[AnyRef] = { val converted = mutable.ArrayBuffer.empty[AnyRef] memo += obj -> converted for ((value, index) <- list) { @@ -240,7 +239,7 @@ private[oc] object Registry extends api.detail.DriverAPI { converted.toArray } - def convertMap(obj: AnyRef, map: Map[_, _], memo: util.IdentityHashMap[AnyRef, AnyRef]): AnyRef = { + def convertMap[K, V](obj: Any, map: Map[K, V], memo: util.IdentityHashMap[Any, AnyRef]): AnyRef = { val converted = memo.getOrElseUpdate(obj, mutable.Map.empty[AnyRef, AnyRef]) match { case map: mutable.Map[AnyRef, AnyRef]@unchecked => map case map: java.util.Map[AnyRef, AnyRef]@unchecked => mapAsScalaMap(map) diff --git a/src/main/scala/li/cil/oc/server/fs/Buffered.scala b/src/main/scala/li/cil/oc/server/fs/Buffered.scala index 0a9443922a..c005462c45 100644 --- a/src/main/scala/li/cil/oc/server/fs/Buffered.scala +++ b/src/main/scala/li/cil/oc/server/fs/Buffered.scala @@ -12,7 +12,7 @@ import li.cil.oc.OpenComputers import li.cil.oc.api.fs.Mode import li.cil.oc.util.ThreadPoolFactory import li.cil.oc.util.SafeThreadPool -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import org.apache.commons.io.FileUtils import scala.collection.mutable @@ -48,7 +48,7 @@ trait Buffered extends OutputStreamFileSystem { private var saving: Option[Future[_]] = None - override def load(nbt: NBTTagCompound): Unit = { + override def loadData(nbt: CompoundNBT): Unit = { saving.foreach(f => try { f.get(120L, TimeUnit.SECONDS) } catch { @@ -56,10 +56,10 @@ trait Buffered extends OutputStreamFileSystem { case e: CancellationException => // NO-OP }) loadFiles(nbt) - super.load(nbt) + super.loadData(nbt) } - private def loadFiles(nbt: NBTTagCompound): Unit = this.synchronized { + private def loadFiles(nbt: CompoundNBT): Unit = this.synchronized { def recurse(path: String, directory: io.File) { makeDirectory(path) for (child <- directory.listFiles() if FileSystem.isValidFilename(child.getName)) { @@ -79,7 +79,7 @@ trait Buffered extends OutputStreamFileSystem { read = in.read(buffer) if (read > 0) { if (read == buffer.length) stream.write(buffer) - else stream.write(buffer.view(0, read).toArray) + else stream.write(buffer.view.slice(0, read).toArray) } } while (read >= 0) in.close() @@ -101,8 +101,8 @@ trait Buffered extends OutputStreamFileSystem { else recurse("", fileRoot) } - override def save(nbt: NBTTagCompound): Unit = { - super.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = { + super.saveData(nbt) saving = Buffered.fileSaveHandler.withPool(_.submit(new Runnable { override def run(): Unit = saveFiles() })) diff --git a/src/main/scala/li/cil/oc/server/fs/Capacity.scala b/src/main/scala/li/cil/oc/server/fs/Capacity.scala index 257e6bf029..54b606414a 100644 --- a/src/main/scala/li/cil/oc/server/fs/Capacity.scala +++ b/src/main/scala/li/cil/oc/server/fs/Capacity.scala @@ -4,7 +4,7 @@ import java.io import li.cil.oc.Settings import li.cil.oc.api.fs.Mode -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT trait Capacity extends OutputStreamFileSystem { private var used = computeSize("/") @@ -52,10 +52,10 @@ trait Capacity extends OutputStreamFileSystem { // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { try { ignoreCapacity = true - super.load(nbt) + super.loadData(nbt) } finally { ignoreCapacity = false } @@ -63,11 +63,11 @@ trait Capacity extends OutputStreamFileSystem { used = computeSize("/") } - override def save(nbt: NBTTagCompound) { - super.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) // For the tooltip. - nbt.setLong("capacity.used", used) + nbt.putLong("capacity.used", used) } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/server/fs/CompositeReadOnlyFileSystem.scala b/src/main/scala/li/cil/oc/server/fs/CompositeReadOnlyFileSystem.scala index d8e4553536..7e5f25d40f 100644 --- a/src/main/scala/li/cil/oc/server/fs/CompositeReadOnlyFileSystem.scala +++ b/src/main/scala/li/cil/oc/server/fs/CompositeReadOnlyFileSystem.scala @@ -7,7 +7,7 @@ import li.cil.oc.api import li.cil.oc.api.fs.Handle import li.cil.oc.api.fs.Mode import li.cil.oc.util.ExtendedNBT._ -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import scala.collection.mutable @@ -82,15 +82,15 @@ class CompositeReadOnlyFileSystem(factories: mutable.LinkedHashMap[String, Calla // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { for ((name, fs) <- parts) { - fs.load(nbt.getCompoundTag(name)) + fs.loadData(nbt.getCompound(name)) } } - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { for ((name, fs) <- parts) { - nbt.setNewCompoundTag(name, fs.save) + nbt.setNewCompoundTag(name, fs.saveData) } } diff --git a/src/main/scala/li/cil/oc/server/fs/FileOutputStreamFileSystem.scala b/src/main/scala/li/cil/oc/server/fs/FileOutputStreamFileSystem.scala index a909e1c6ca..83b1ea7a5e 100644 --- a/src/main/scala/li/cil/oc/server/fs/FileOutputStreamFileSystem.scala +++ b/src/main/scala/li/cil/oc/server/fs/FileOutputStreamFileSystem.scala @@ -4,7 +4,7 @@ import java.io import java.io.RandomAccessFile import li.cil.oc.api.fs.Mode -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT trait FileOutputStreamFileSystem extends FileInputStreamFileSystem with OutputStreamFileSystem { override def spaceTotal = -1 @@ -34,8 +34,8 @@ trait FileOutputStreamFileSystem extends FileInputStreamFileSystem with OutputSt // ----------------------------------------------------------------------- // - override def save(nbt: NBTTagCompound) { - super.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) root.mkdirs() root.setLastModified(System.currentTimeMillis()) } diff --git a/src/main/scala/li/cil/oc/server/fs/FileSystem.scala b/src/main/scala/li/cil/oc/server/fs/FileSystem.scala index ef3451bf9e..53874c8b20 100755 --- a/src/main/scala/li/cil/oc/server/fs/FileSystem.scala +++ b/src/main/scala/li/cil/oc/server/fs/FileSystem.scala @@ -11,20 +11,23 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.fs.Label import li.cil.oc.api.network.EnvironmentHost -import li.cil.oc.common.item.Delegator import li.cil.oc.common.item.traits.FileSystemLike import li.cil.oc.server.component import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.common.DimensionManager +import net.minecraft.nbt.CompoundNBT +import net.minecraft.util.ResourceLocation +import net.minecraft.world.storage.FolderName +import net.minecraftforge.fml.loading.FMLLoader +import net.minecraftforge.fml.server.ServerLifecycleHooks import scala.util.Try object FileSystem extends api.detail.FileSystemAPI { lazy val isCaseInsensitive: Boolean = Settings.get.forceCaseInsensitive || (try { val uuid = UUID.randomUUID().toString - val lowerCase = new io.File(DimensionManager.getCurrentSaveRootDirectory, uuid + "oc_rox") - val upperCase = new io.File(DimensionManager.getCurrentSaveRootDirectory, uuid + "OC_ROX") + val saveDir = ServerLifecycleHooks.getCurrentServer.getWorldPath(FolderName.ROOT).toFile + val lowerCase = new io.File(saveDir, uuid + "oc_rox") + val upperCase = new io.File(saveDir, uuid + "OC_ROX") // This should NEVER happen but could also lead to VERY weird bugs, so we // make sure the files don't exist. lowerCase.exists() && lowerCase.delete() @@ -57,50 +60,27 @@ object FileSystem extends api.detail.FileSystemAPI { path } - override def fromClass(clazz: Class[_], domain: String, root: String): api.fs.FileSystem = { - val innerPath = ("/assets/" + domain + "/" + (root.trim + "/")).replace("//", "/") - - val codeSource = clazz.getProtectionDomain.getCodeSource.getLocation.getPath - val (codeUrl, isArchive) = - if (codeSource.contains(".zip!") || codeSource.contains(".jar!")) - (codeSource.substring(0, codeSource.lastIndexOf('!')), true) - else - (codeSource, false) - - val url = Try { - new URL(codeUrl) - }.recoverWith { - case _: MalformedURLException => Try { - new URL("file://" + codeUrl) - } - } - val file = url.map(url => new io.File(url.toURI)).recoverWith { - case _: URISyntaxException => url.map(url => new io.File(url.getPath)) - }.getOrElse(new io.File(codeSource)) + override def fromResource(loc: ResourceLocation): api.fs.FileSystem = { + val innerPath = "/assets/" + loc.getNamespace + "/" + (loc.getPath.trim + "/") - if (isArchive) { + val modInfo = FMLLoader.getLoadingModList().getModFileById(loc.getNamespace) + val file = modInfo.getFile().getFilePath().toFile() + + if (!file.exists) return null + if (!file.isDirectory) { ZipFileInputStreamFileSystem.fromFile(file, innerPath.substring(1)) } else { - if (!file.exists || file.isDirectory) return null - new io.File(new io.File(file.getParent), innerPath) match { + new io.File(file, innerPath) match { case fsp if fsp.exists() && fsp.isDirectory => new ReadOnlyFileSystem(fsp) - case _ => - System.getProperty("java.class.path").split(System.getProperty("path.separator")). - find(cp => { - val fsp = new io.File(new io.File(cp), innerPath) - fsp.exists() && fsp.isDirectory - }) match { - case None => null - case Some(dir) => new ReadOnlyFileSystem(new io.File(new io.File(dir), innerPath)) - } + case _ => null } } } override def fromSaveDirectory(root: String, capacity: Long, buffered: Boolean): Capacity = { - val path = new io.File(DimensionManager.getCurrentSaveRootDirectory, Settings.savePath + root) + val path = ServerLifecycleHooks.getCurrentServer.getWorldPath(new FolderName(Settings.savePath + root)).toFile if (!path.isDirectory) { path.delete() } @@ -113,13 +93,13 @@ object FileSystem extends api.detail.FileSystemAPI { } def removeAddress(fsStack: ItemStack): Boolean = { - Delegator.subItem(fsStack) match { - case Some(drive: FileSystemLike) => { + fsStack.getItem match { + case drive: FileSystemLike => { val data = li.cil.oc.integration.opencomputers.Item.dataTag(fsStack) - if (data.hasKey("node")) { - val nodeData = data.getCompoundTag("node") - if (nodeData.hasKey("address")) { - nodeData.removeTag("address") + if (data.contains("node")) { + val nodeData = data.getCompound("node") + if (nodeData.contains("address")) { + nodeData.remove("address") return true } } @@ -167,11 +147,11 @@ object FileSystem extends api.detail.FileSystemAPI { private final val LabelTag = Settings.namespace + "fs.label" - override def load(nbt: NBTTagCompound) {} + override def loadData(nbt: CompoundNBT) {} - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { if (label != null) { - nbt.setString(LabelTag, label) + nbt.putString(LabelTag, label) } } } diff --git a/src/main/scala/li/cil/oc/server/fs/InputStreamFileSystem.scala b/src/main/scala/li/cil/oc/server/fs/InputStreamFileSystem.scala index 67a554ef9f..11a986482c 100644 --- a/src/main/scala/li/cil/oc/server/fs/InputStreamFileSystem.scala +++ b/src/main/scala/li/cil/oc/server/fs/InputStreamFileSystem.scala @@ -7,8 +7,8 @@ import java.nio.channels.ReadableByteChannel import li.cil.oc.api import li.cil.oc.api.fs.Mode -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagList +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.ListNBT import net.minecraftforge.common.util.Constants.NBT import scala.collection.mutable @@ -58,10 +58,10 @@ trait InputStreamFileSystem extends api.fs.FileSystem { private final val PathTag = "path" private final val PositionTag = "position" - override def load(nbt: NBTTagCompound) { - val handlesNbt = nbt.getTagList(InputTag, NBT.TAG_COMPOUND) - (0 until handlesNbt.tagCount).map(handlesNbt.getCompoundTagAt).foreach(handleNbt => { - val handle = handleNbt.getInteger(HandleTag) + override def loadData(nbt: CompoundNBT) { + val handlesNbt = nbt.getList(InputTag, NBT.TAG_COMPOUND) + (0 until handlesNbt.size).map(handlesNbt.getCompound).foreach(handleNbt => { + val handle = handleNbt.getInt(HandleTag) val path = handleNbt.getString(PathTag) val position = handleNbt.getLong(PositionTag) openInputChannel(path) match { @@ -74,17 +74,17 @@ trait InputStreamFileSystem extends api.fs.FileSystem { }) } - override def save(nbt: NBTTagCompound) = this.synchronized { - val handlesNbt = new NBTTagList() + override def saveData(nbt: CompoundNBT): Unit = this.synchronized { + val handlesNbt = new ListNBT() for (file <- handles.values) { assert(file.channel.isOpen) - val handleNbt = new NBTTagCompound() - handleNbt.setInteger(HandleTag, file.handle) - handleNbt.setString(PathTag, file.path) - handleNbt.setLong(PositionTag, file.position) - handlesNbt.appendTag(handleNbt) + val handleNbt = new CompoundNBT() + handleNbt.putInt(HandleTag, file.handle) + handleNbt.putString(PathTag, file.path) + handleNbt.putLong(PositionTag, file.position) + handlesNbt.add(handleNbt) } - nbt.setTag(InputTag, handlesNbt) + nbt.put(InputTag, handlesNbt) } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/server/fs/OutputStreamFileSystem.scala b/src/main/scala/li/cil/oc/server/fs/OutputStreamFileSystem.scala index 4877aaa4d4..d0b7bbc7b7 100644 --- a/src/main/scala/li/cil/oc/server/fs/OutputStreamFileSystem.scala +++ b/src/main/scala/li/cil/oc/server/fs/OutputStreamFileSystem.scala @@ -5,8 +5,8 @@ import java.io.IOException import li.cil.oc.api import li.cil.oc.api.fs.Mode -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagList +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.ListNBT import net.minecraftforge.common.util.Constants.NBT import scala.collection.mutable @@ -50,12 +50,12 @@ trait OutputStreamFileSystem extends InputStreamFileSystem { private final val HandleTag = "handle" private final val PathTag = "path" - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) - val handlesNbt = nbt.getTagList(OutputTag, NBT.TAG_COMPOUND) - (0 until handlesNbt.tagCount).map(handlesNbt.getCompoundTagAt).foreach(handleNbt => { - val handle = handleNbt.getInteger(HandleTag) + val handlesNbt = nbt.getList(OutputTag, NBT.TAG_COMPOUND) + (0 until handlesNbt.size).map(handlesNbt.getCompound).foreach(handleNbt => { + val handle = handleNbt.getInt(HandleTag) val path = handleNbt.getString(PathTag) openOutputHandle(handle, path, Mode.Append) match { case Some(fileHandle) => handles += handle -> fileHandle @@ -64,18 +64,18 @@ trait OutputStreamFileSystem extends InputStreamFileSystem { }) } - override def save(nbt: NBTTagCompound) = this.synchronized { - super.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = this.synchronized { + super.saveData(nbt) - val handlesNbt = new NBTTagList() + val handlesNbt = new ListNBT() for (file <- handles.values) { assert(!file.isClosed) - val handleNbt = new NBTTagCompound() - handleNbt.setInteger(HandleTag, file.handle) - handleNbt.setString(PathTag, file.path) - handlesNbt.appendTag(handleNbt) + val handleNbt = new CompoundNBT() + handleNbt.putInt(HandleTag, file.handle) + handleNbt.putString(PathTag, file.path) + handlesNbt.add(handleNbt) } - nbt.setTag(OutputTag, handlesNbt) + nbt.put(OutputTag, handlesNbt) } // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/server/fs/ReadOnlyWrapper.scala b/src/main/scala/li/cil/oc/server/fs/ReadOnlyWrapper.scala index 2c4a2dde51..9ead60b6ed 100644 --- a/src/main/scala/li/cil/oc/server/fs/ReadOnlyWrapper.scala +++ b/src/main/scala/li/cil/oc/server/fs/ReadOnlyWrapper.scala @@ -4,7 +4,7 @@ import java.io.FileNotFoundException import li.cil.oc.api import li.cil.oc.api.fs.Mode -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT private class ReadOnlyWrapper(val fileSystem: api.fs.FileSystem) extends api.fs.FileSystem { override def isReadOnly = true @@ -41,7 +41,7 @@ private class ReadOnlyWrapper(val fileSystem: api.fs.FileSystem) extends api.fs. override def close() = fileSystem.close() - override def load(nbt: NBTTagCompound) = fileSystem.load(nbt) + override def loadData(nbt: CompoundNBT): Unit = fileSystem.loadData(nbt) - override def save(nbt: NBTTagCompound) = fileSystem.save(nbt) + override def saveData(nbt: CompoundNBT): Unit = fileSystem.saveData(nbt) } diff --git a/src/main/scala/li/cil/oc/server/fs/VirtualFileSystem.scala b/src/main/scala/li/cil/oc/server/fs/VirtualFileSystem.scala index 02a63fdcb3..24f8578ea5 100644 --- a/src/main/scala/li/cil/oc/server/fs/VirtualFileSystem.scala +++ b/src/main/scala/li/cil/oc/server/fs/VirtualFileSystem.scala @@ -4,8 +4,8 @@ import java.io import java.io.FileNotFoundException import li.cil.oc.api.fs.Mode -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagList +import net.minecraft.nbt.CompoundNBT +import net.minecraft.nbt.ListNBT import net.minecraftforge.common.util.Constants.NBT import scala.collection.mutable @@ -123,14 +123,14 @@ trait VirtualFileSystem extends OutputStreamFileSystem { // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) = { - if (!this.isInstanceOf[Buffered]) root.load(nbt) - super.load(nbt) // Last to ensure streams can be re-opened. + override def loadData(nbt: CompoundNBT) { + if (!this.isInstanceOf[Buffered]) root.loadData(nbt) + super.loadData(nbt) // Last to ensure streams can be re-opened. } - override def save(nbt: NBTTagCompound) = { - super.save(nbt) // First to allow flushing. - if (!this.isInstanceOf[Buffered]) root.save(nbt) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) // First to allow flushing. + if (!this.isInstanceOf[Buffered]) root.saveData(nbt) } // ----------------------------------------------------------------------- // @@ -146,13 +146,13 @@ trait VirtualFileSystem extends OutputStreamFileSystem { var lastModified = System.currentTimeMillis() - def load(nbt: NBTTagCompound) { - if (nbt.hasKey("lastModified")) + def loadData(nbt: CompoundNBT) { + if (nbt.contains("lastModified")) lastModified = nbt.getLong("lastModified") } - def save(nbt: NBTTagCompound) { - nbt.setLong("lastModified", lastModified) + def saveData(nbt: CompoundNBT) { + nbt.putLong("lastModified", lastModified) } def get(path: Iterable[String]): Option[VirtualObject] = @@ -185,15 +185,15 @@ trait VirtualFileSystem extends OutputStreamFileSystem { handle } - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) data.clear() data ++= nbt.getByteArray("data") } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setByteArray("data", data.toArray) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putByteArray("data", data.toArray) } override def canDelete = handle.isEmpty @@ -245,29 +245,29 @@ trait VirtualFileSystem extends OutputStreamFileSystem { private final val IsDirectoryTag = "isDirectory" private final val NameTag = "name" - override def load(nbt: NBTTagCompound) { - super.load(nbt) - val childrenNbt = nbt.getTagList(ChildrenTag, NBT.TAG_COMPOUND) - (0 until childrenNbt.tagCount).map(childrenNbt.getCompoundTagAt).foreach(childNbt => { + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + val childrenNbt = nbt.getList(ChildrenTag, NBT.TAG_COMPOUND) + (0 until childrenNbt.size).map(childrenNbt.getCompound).foreach(childNbt => { val child = if (childNbt.getBoolean(IsDirectoryTag)) new VirtualDirectory else new VirtualFile - child.load(childNbt) + child.loadData(childNbt) children += childNbt.getString(NameTag) -> child }) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - val childrenNbt = new NBTTagList() + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + val childrenNbt = new ListNBT() for ((childName, child) <- children) { - val childNbt = new NBTTagCompound() - childNbt.setBoolean(IsDirectoryTag, child.isDirectory) - childNbt.setString(NameTag, childName) - child.save(childNbt) - childrenNbt.appendTag(childNbt) + val childNbt = new CompoundNBT() + childNbt.putBoolean(IsDirectoryTag, child.isDirectory) + childNbt.putString(NameTag, childName) + child.saveData(childNbt) + childrenNbt.add(childNbt) } - nbt.setTag(ChildrenTag, childrenNbt) + nbt.put(ChildrenTag, childrenNbt) } override def get(path: Iterable[String]) = diff --git a/src/main/scala/li/cil/oc/server/loot/CopyColor.java b/src/main/scala/li/cil/oc/server/loot/CopyColor.java new file mode 100644 index 0000000000..5266a33918 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/loot/CopyColor.java @@ -0,0 +1,60 @@ +package li.cil.oc.server.loot; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import li.cil.oc.api.internal.Colored; +import li.cil.oc.util.ItemColorizer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.loot.LootContext; +import net.minecraft.loot.LootFunction; +import net.minecraft.loot.LootFunctionType; +import net.minecraft.loot.LootParameters; +import net.minecraft.loot.functions.ILootFunction; +import net.minecraft.loot.conditions.ILootCondition; + +public final class CopyColor extends LootFunction { + private CopyColor(ILootCondition[] conditions) { + super(conditions); + } + + @Override + public LootFunctionType getType() { + return LootFunctions.COPY_COLOR; + } + + public static class Builder extends LootFunction.Builder { + @Override + protected Builder getThis() { + return this; + } + + @Override + public ILootFunction build() { + return new CopyColor(getConditions()); + } + } + + public static Builder copyColor() { + return new Builder(); + } + + @Override + public ItemStack run(ItemStack stack, LootContext ctx) { + if (stack.isEmpty()) return stack; + TileEntity te = ctx.getParamOrNull(LootParameters.BLOCK_ENTITY); + if (te != null && te instanceof Colored) { + // Can't use capability because it's already invalid - block breaks before drops are calculated. + ItemColorizer.setColor(stack, ((Colored) te).getColor()); + } + else ItemColorizer.removeColor(stack); + return stack; + } + + public static class Serializer extends LootFunction.Serializer { + @Override + public CopyColor deserialize(JsonObject src, JsonDeserializationContext ctx, ILootCondition[] conditions) { + return new CopyColor(conditions); + } + } +} diff --git a/src/main/scala/li/cil/oc/server/loot/LootFunctions.java b/src/main/scala/li/cil/oc/server/loot/LootFunctions.java new file mode 100644 index 0000000000..fbd8b77e38 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/loot/LootFunctions.java @@ -0,0 +1,29 @@ +package li.cil.oc.server.loot; + +import li.cil.oc.OpenComputers; +import net.minecraft.loot.ILootSerializer; +import net.minecraft.loot.LootFunctionType; +import net.minecraft.loot.functions.ILootFunction; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.Registry; + +public final class LootFunctions { + public static final ResourceLocation DYN_ITEM_DATA = new ResourceLocation(OpenComputers.ID(), "item_data"); + public static final ResourceLocation DYN_VOLATILE_CONTENTS = new ResourceLocation(OpenComputers.ID(), "volatile_contents"); + + public static final LootFunctionType SET_COLOR = register("set_color", new SetColor.Serializer()); + public static final LootFunctionType COPY_COLOR = register("copy_color", new CopyColor.Serializer()); + + private static LootFunctionType register(String name, ILootSerializer serializer) { + LootFunctionType type = new LootFunctionType(serializer); + Registry.register(Registry.LOOT_FUNCTION_TYPE, new ResourceLocation(OpenComputers.ID(), name), type); + return type; + } + + public static final void init() { + // No registry events or ObjectHolder - this is to load the class. + } + + private LootFunctions() { + } +} diff --git a/src/main/scala/li/cil/oc/server/loot/SetColor.java b/src/main/scala/li/cil/oc/server/loot/SetColor.java new file mode 100644 index 0000000000..61b247fb29 --- /dev/null +++ b/src/main/scala/li/cil/oc/server/loot/SetColor.java @@ -0,0 +1,88 @@ +package li.cil.oc.server.loot; + +import java.util.OptionalInt; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import li.cil.oc.util.ItemColorizer; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.LootContext; +import net.minecraft.loot.LootFunction; +import net.minecraft.loot.LootFunctionType; +import net.minecraft.loot.functions.ILootFunction; +import net.minecraft.loot.conditions.ILootCondition; +import net.minecraft.util.JSONUtils; + +public final class SetColor extends LootFunction { + private OptionalInt color; + + private SetColor(ILootCondition[] conditions, OptionalInt color) { + super(conditions); + this.color = color; + } + + @Override + public LootFunctionType getType() { + return LootFunctions.SET_COLOR; + } + + @Override + public ItemStack run(ItemStack stack, LootContext ctx) { + if (stack.isEmpty()) return stack; + if (color.isPresent()) { + ItemColorizer.setColor(stack, color.getAsInt()); + } + else ItemColorizer.removeColor(stack); + return stack; + } + + public static class Builder extends LootFunction.Builder { + private OptionalInt color = OptionalInt.empty(); + + @Override + protected Builder getThis() { + return this; + } + + public Builder withoutColor() { + color = OptionalInt.empty(); + return this; + } + + public Builder withColor(int color) { + if (color < 0 || color > 0xFFFFFF) throw new IllegalArgumentException("Invalid RGB color: " + color); + this.color = OptionalInt.of(color); + return this; + } + + @Override + public ILootFunction build() { + return new SetColor(getConditions(), color); + } + } + + public static Builder setColor() { + return new Builder(); + } + + public static class Serializer extends LootFunction.Serializer { + @Override + public void serialize(JsonObject dst, SetColor src, JsonSerializationContext ctx) { + super.serialize(dst, src, ctx); + src.color.ifPresent(v -> dst.add("color", new JsonPrimitive(v))); + } + + @Override + public SetColor deserialize(JsonObject src, JsonDeserializationContext ctx, ILootCondition[] conditions) { + if (src.has("color")) { + int color = JSONUtils.getAsInt(src, "color"); + if (color < 0 || color > 0xFFFFFF) throw new JsonParseException("Invalid RGB color: " + color); + return new SetColor(conditions, OptionalInt.of(color)); + } + else return new SetColor(conditions, OptionalInt.empty()); + } + } +} diff --git a/src/main/scala/li/cil/oc/server/machine/ArchitectureAPI.scala b/src/main/scala/li/cil/oc/server/machine/ArchitectureAPI.scala index 656ab58152..141b9717d2 100644 --- a/src/main/scala/li/cil/oc/server/machine/ArchitectureAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/ArchitectureAPI.scala @@ -1,7 +1,7 @@ package li.cil.oc.server.machine import li.cil.oc.api -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT abstract class ArchitectureAPI(val machine: api.machine.Machine) { protected def node = machine.node @@ -10,7 +10,7 @@ abstract class ArchitectureAPI(val machine: api.machine.Machine) { def initialize(): Unit - def load(nbt: NBTTagCompound) {} + def loadData(nbt: CompoundNBT) {} - def save(nbt: NBTTagCompound) {} + def saveData(nbt: CompoundNBT) {} } diff --git a/src/main/scala/li/cil/oc/server/machine/ArgumentsImpl.scala b/src/main/scala/li/cil/oc/server/machine/ArgumentsImpl.scala index f5873a7fc7..1b7bd22ab2 100644 --- a/src/main/scala/li/cil/oc/server/machine/ArgumentsImpl.scala +++ b/src/main/scala/li/cil/oc/server/machine/ArgumentsImpl.scala @@ -5,12 +5,14 @@ import java.util import com.google.common.base.Charsets import li.cil.oc.api.machine.Arguments import li.cil.oc.util.ItemUtils +import li.cil.oc.util.ResultWrapper import net.minecraft.item.Item import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import net.minecraft.util.ResourceLocation +import net.minecraftforge.registries.ForgeRegistries -import scala.collection.convert.WrapAsJava._ +import scala.collection.convert.ImplicitConversionsToJava._ import scala.collection.mutable class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments { @@ -21,7 +23,7 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments { def checkAny(index: Int) = { checkIndex(index, "value") args(index) match { - case Unit | None => null + case ResultWrapper.unit | None => null case arg => arg } } @@ -208,7 +210,7 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments { s"bad argument #${index + 1} ($want expected, got ${typeName(have)})") private def typeName(value: AnyRef): String = value match { - case null | Unit | None => "nil" + case null | ResultWrapper.unit | None => "nil" case _: java.lang.Boolean => "boolean" case _: java.lang.Number => "double" case _: java.lang.String => "string" @@ -219,11 +221,12 @@ class ArgumentsImpl(val args: Seq[AnyRef]) extends Arguments { case _ => value.getClass.getSimpleName } - private def makeStack(name: String, damage: Int, tag: Option[NBTTagCompound]) = { - Item.REGISTRY.getObject(new ResourceLocation(name)) match { + private def makeStack(name: String, damage: Int, tag: Option[CompoundNBT]) = { + ForgeRegistries.ITEMS.getValue(new ResourceLocation(name)) match { case item: Item => - val stack = new ItemStack(item, 1, damage) - tag.foreach(stack.setTagCompound) + val stack = new ItemStack(item, 1) + stack.setDamageValue(damage) + tag.foreach(stack.setTag) stack case _ => throw new IllegalArgumentException("invalid item stack") } diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index 40b707cc72..718b5a12c6 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -35,19 +35,20 @@ import li.cil.oc.server.PacketSender import li.cil.oc.server.driver.Registry import li.cil.oc.server.fs.FileSystem import li.cil.oc.util.ExtendedNBT._ +import li.cil.oc.util.ResultWrapper import li.cil.oc.util.ResultWrapper.result import li.cil.oc.util.ThreadPoolFactory import net.minecraft.client.Minecraft -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.player.PlayerEntity import net.minecraft.item.ItemStack import net.minecraft.nbt._ import net.minecraft.server.integrated.IntegratedServer import net.minecraftforge.common.util.Constants.NBT -import net.minecraftforge.fml.common.FMLCommonHandler +import net.minecraftforge.fml.server.ServerLifecycleHooks -import scala.Array.canBuildFrom -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.mapAsJavaMap +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable class Machine(val host: MachineHost) extends AbstractManagedEnvironment with machine.Machine with Runnable with DeviceInfo { @@ -152,7 +153,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac hasMemory = Option(architecture).fold(false)(_.recomputeMemory(components)) } - override def components: util.Map[String, String] = scala.collection.convert.WrapAsJava.mapAsJavaMap(_components) + override def components: util.Map[String, String] = mapAsJavaMap(_components) def componentCount: Int = (_components.foldLeft(0.0)((acc, entry) => entry match { case (_, name) => acc + (if (name != "filesystem") 1.0 else 0.25) @@ -192,10 +193,11 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac override def canInteract(player: String): Boolean = !Settings.get.canComputersBeOwned || _users.synchronized(_users.isEmpty || _users.contains(player)) || - FMLCommonHandler.instance.getMinecraftServerInstance.isSinglePlayer || { - val config = FMLCommonHandler.instance.getMinecraftServerInstance.getPlayerList - val entity = config.getPlayerByUsername(player) - entity != null && config.canSendCommands(entity.getGameProfile) + ServerLifecycleHooks.getCurrentServer == null || + ServerLifecycleHooks.getCurrentServer.isSingleplayer || { + val config = ServerLifecycleHooks.getCurrentServer.getPlayerList + val entity = config.getPlayerByName(player) + entity != null && config.isOp(entity.getGameProfile) } override def isRunning: Boolean = state.synchronized(state.top != Machine.State.Stopped && state.top != Machine.State.Stopping) @@ -319,7 +321,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac case arg: java.lang.Number => Double.box(arg.doubleValue) case arg: java.lang.String => arg case arg: Array[Byte] => arg - case arg: NBTTagCompound => arg + case arg: CompoundNBT => arg case arg => OpenComputers.log.warn("Trying to push signal with an unsupported argument of type " + arg.getClass.getName) null @@ -336,7 +338,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac } else { signals.enqueue(new Machine.Signal(name, args.map { - case null | Unit | None => null + case null | ResultWrapper.unit | None => null case arg: Map[_, _] if arg.isEmpty || arg.head._1.isInstanceOf[String] && arg.head._2.isInstanceOf[String] => arg case arg: mutable.Map[_, _] if arg.isEmpty || arg.head._1.isInstanceOf[String] && arg.head._2.isInstanceOf[String] => arg.toMap case arg: java.util.Map[_, _] => { @@ -409,7 +411,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac throw new Exception("user exists") if (name.length > Settings.get.maxUsernameLength) throw new Exception("username too long") - if (!FMLCommonHandler.instance.getMinecraftServerInstance.getOnlinePlayerNames.contains(name)) + if (!ServerLifecycleHooks.getCurrentServer.getPlayerNames.contains(name)) throw new Exception("player must be online") _users.synchronized { @@ -509,7 +511,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac } // Update world time for time() and uptime(). - worldTime = host.world.getWorldTime + worldTime = host.world.getDayTime uptime += 1 if (remainIdle > 0) { @@ -520,7 +522,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac callBudget = maxCallBudget // Make sure we have enough power. - if (host.world.getTotalWorldTime % Settings.get.tickFrequency == 0) { + if (host.world.getGameTime % Settings.get.tickFrequency == 0) { state.synchronized(state.top match { case Machine.State.Paused | Machine.State.Restarting | @@ -538,7 +540,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac } // Avoid spamming user list across the network. - if (host.world.getTotalWorldTime % 20 == 0 && usersChanged) { + if (host.world.getGameTime % 20 == 0 && usersChanged) { val list = _users.synchronized { usersChanged = false users @@ -631,8 +633,8 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac message.data match { case Array(name: String, args@_*) if message.name == "computer.signal" => signal(name, Seq(message.source.address) ++ args: _*) - case Array(player: EntityPlayer, name: String, args@_*) if message.name == "computer.checked_signal" => - if (canInteract(player.getName)) + case Array(player: PlayerEntity, name: String, args@_*) if message.name == "computer.checked_signal" => + if (canInteract(player.getName.getString)) signal(name, Seq(message.source.address) ++ args: _*) case _ => if (message.name == "computer.start" && !isPaused) start() @@ -741,55 +743,55 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac private final val CPUTimeTag = "cpuTime" private final val RemainingPauseTag = "remainingPause" - override def load(nbt: NBTTagCompound): Unit = Machine.this.synchronized(state.synchronized { + override def loadData(nbt: CompoundNBT): Unit = Machine.this.synchronized(state.synchronized { assert(state.top == Machine.State.Stopped || state.top == Machine.State.Paused) close() state.clear() - super.load(nbt) + super.loadData(nbt) state.pushAll(nbt.getIntArray(StateTag).reverseMap(Machine.State(_))) - nbt.getTagList(UsersTag, NBT.TAG_STRING).foreach((tag: NBTTagString) => _users += tag.getString) - if (nbt.hasKey(MessageTag)) { + nbt.getList(UsersTag, NBT.TAG_STRING).foreach((tag: StringNBT) => _users += tag.getAsString) + if (nbt.contains(MessageTag)) { message = Some(nbt.getString(MessageTag)) } - _components ++= nbt.getTagList(ComponentsTag, NBT.TAG_COMPOUND).map((tag: NBTTagCompound) => + _components ++= nbt.getList(ComponentsTag, NBT.TAG_COMPOUND).map((tag: CompoundNBT) => tag.getString(AddressTag) -> tag.getString(NameTag)) tmp.foreach(fs => { - if (nbt.hasKey(TmpTag)) fs.load(nbt.getCompoundTag(TmpTag)) - else fs.load(SaveHandler.loadNBT(nbt, tmpPath)) + if (nbt.contains(TmpTag)) fs.loadData(nbt.getCompound(TmpTag)) + else fs.loadData(SaveHandler.loadNBT(nbt, tmpPath)) }) if (state.nonEmpty && isRunning && init()) try { - architecture.load(nbt) + architecture.loadData(nbt) - signals ++= nbt.getTagList(SignalsTag, NBT.TAG_COMPOUND).map((signalNbt: NBTTagCompound) => { - val argsNbt = signalNbt.getCompoundTag(ArgsTag) - val argsLength = argsNbt.getInteger(LengthTag) + signals ++= nbt.getList(SignalsTag, NBT.TAG_COMPOUND).map((signalNbt: CompoundNBT) => { + val argsNbt = signalNbt.getCompound(ArgsTag) + val argsLength = argsNbt.getInt(LengthTag) new Machine.Signal(signalNbt.getString(NameTag), - (0 until argsLength).map(ArgPrefixTag + _).map(argsNbt.getTag).map { - case tag: NBTTagByte if tag.getByte == -1 => null - case tag: NBTTagByte => Boolean.box(tag.getByte == 1) - case tag: NBTTagLong => Long.box(tag.getLong) - case tag: NBTTagDouble => Double.box(tag.getDouble) - case tag: NBTTagString => tag.getString - case tag: NBTTagByteArray => tag.getByteArray - case tag: NBTTagList => + (0 until argsLength).map(ArgPrefixTag + _).map(argsNbt.get).map { + case tag: ByteNBT if tag.getAsByte == -1 => null + case tag: ByteNBT => Boolean.box(tag.getAsByte == 1) + case tag: LongNBT => Long.box(tag.getAsLong) + case tag: DoubleNBT => Double.box(tag.getAsDouble) + case tag: StringNBT => tag.getAsString + case tag: ByteArrayNBT => tag.getAsByteArray + case tag: ListNBT => val data = mutable.Map.empty[String, String] - for (i <- 0 until tag.tagCount by 2) { - data += tag.getStringTagAt(i) -> tag.getStringTagAt(i + 1) + for (i <- 0 until tag.size by 2) { + data += tag.getString(i) -> tag.getString(i + 1) } data - case tag: NBTTagCompound => tag + case tag: CompoundNBT => tag case _ => null }.toArray[AnyRef]) }) uptime = nbt.getLong(UptimeTag) cpuTotal = nbt.getLong(CPUTimeTag) - remainingPause = nbt.getInteger(RemainingPauseTag) + remainingPause = nbt.getInt(RemainingPauseTag) // Delay execution for a second to allow the world around us to settle. if (state.top != Machine.State.Restarting) { @@ -810,7 +812,7 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac } }) - override def save(nbt: NBTTagCompound): Unit = Machine.this.synchronized(state.synchronized { + override def saveData(nbt: CompoundNBT): Unit = Machine.this.synchronized(state.synchronized { // The lock on 'this' should guarantee that this never happens regularly. // If something other than regular saving tries to save while we are executing code, // e.g. SpongeForge saving during robot.move due to block changes being captured, @@ -824,60 +826,60 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac // Make sure we don't continue running until everything has saved. pause(0.05) - super.save(nbt) + super.saveData(nbt) // Make sure the component list is up-to-date. processAddedComponents() - nbt.setIntArray(StateTag, state.map(_.id).toArray) + nbt.putIntArray(StateTag, state.map(_.id).toArray) nbt.setNewTagList(UsersTag, _users) - message.foreach(nbt.setString(MessageTag, _)) + message.foreach(nbt.putString(MessageTag, _)) - val componentsNbt = new NBTTagList() + val componentsNbt = new ListNBT() for ((address, name) <- _components) { - val componentNbt = new NBTTagCompound() - componentNbt.setString(AddressTag, address) - componentNbt.setString(NameTag, name) - componentsNbt.appendTag(componentNbt) + val componentNbt = new CompoundNBT() + componentNbt.putString(AddressTag, address) + componentNbt.putString(NameTag, name) + componentsNbt.add(componentNbt) } - nbt.setTag(ComponentsTag, componentsNbt) + nbt.put(ComponentsTag, componentsNbt) - tmp.foreach(fs => SaveHandler.scheduleSave(host, nbt, tmpPath, fs.save _)) + tmp.foreach(fs => SaveHandler.scheduleSave(host, nbt, tmpPath, fs.saveData _)) if (state.top != Machine.State.Stopped) try { - architecture.save(nbt) + architecture.saveData(nbt) - val signalsNbt = new NBTTagList() + val signalsNbt = new ListNBT() for (s <- signals.iterator) { - val signalNbt = new NBTTagCompound() - signalNbt.setString(NameTag, s.name) + val signalNbt = new CompoundNBT() + signalNbt.putString(NameTag, s.name) signalNbt.setNewCompoundTag(ArgsTag, args => { - args.setInteger(LengthTag, s.args.length) + args.putInt(LengthTag, s.args.length) s.args.zipWithIndex.foreach { - case (null, i) => args.setByte(ArgPrefixTag + i, -1) - case (arg: java.lang.Boolean, i) => args.setByte(ArgPrefixTag + i, if (arg) 1 else 0) - case (arg: java.lang.Long, i) => args.setLong(ArgPrefixTag + i, arg) - case (arg: java.lang.Double, i) => args.setDouble(ArgPrefixTag + i, arg) - case (arg: String, i) => args.setString(ArgPrefixTag + i, arg) - case (arg: Array[Byte], i) => args.setByteArray(ArgPrefixTag + i, arg) + case (null, i) => args.putByte(ArgPrefixTag + i, -1) + case (arg: java.lang.Boolean, i) => args.putByte(ArgPrefixTag + i, if (arg) 1 else 0) + case (arg: java.lang.Long, i) => args.putLong(ArgPrefixTag + i, arg) + case (arg: java.lang.Double, i) => args.putDouble(ArgPrefixTag + i, arg) + case (arg: String, i) => args.putString(ArgPrefixTag + i, arg) + case (arg: Array[Byte], i) => args.putByteArray(ArgPrefixTag + i, arg) case (arg: Map[_, _], i) => - val list = new NBTTagList() + val list = new ListNBT() for ((key, value) <- arg) { list.append(key.toString) list.append(value.toString) } - args.setTag(ArgPrefixTag + i, list) - case (arg: NBTTagCompound, i) => args.setTag(ArgPrefixTag + i, arg) - case (_, i) => args.setByte(ArgPrefixTag + i, -1) + args.put(ArgPrefixTag + i, list) + case (arg: CompoundNBT, i) => args.put(ArgPrefixTag + i, arg) + case (_, i) => args.putByte(ArgPrefixTag + i, -1) } }) - signalsNbt.appendTag(signalNbt) + signalsNbt.add(signalNbt) } - nbt.setTag(SignalsTag, signalsNbt) + nbt.put(SignalsTag, signalsNbt) - nbt.setLong(UptimeTag, uptime) - nbt.setLong(CPUTimeTag, cpuTotal) - nbt.setInteger(RemainingPauseTag, remainingPause) + nbt.putLong(UptimeTag, uptime) + nbt.putLong(CPUTimeTag, cpuTotal) + nbt.putInt(RemainingPauseTag, remainingPause) } catch { case t: Throwable => @@ -966,8 +968,8 @@ class Machine(val host: MachineHost) extends AbstractManagedEnvironment with mac result } - private def isGamePaused = FMLCommonHandler.instance.getMinecraftServerInstance != null && !FMLCommonHandler.instance.getMinecraftServerInstance.isDedicatedServer && (FMLCommonHandler.instance.getMinecraftServerInstance match { - case integrated: IntegratedServer => Minecraft.getMinecraft.isGamePaused + private def isGamePaused = ServerLifecycleHooks.getCurrentServer != null && !ServerLifecycleHooks.getCurrentServer.isDedicatedServer && (ServerLifecycleHooks.getCurrentServer match { + case integrated: IntegratedServer => Minecraft.getInstance.isPaused case _ => false }) diff --git a/src/main/scala/li/cil/oc/server/machine/luac/ComponentAPI.scala b/src/main/scala/li/cil/oc/server/machine/luac/ComponentAPI.scala index 8c724ff7a3..c947f56965 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/ComponentAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/ComponentAPI.scala @@ -3,7 +3,7 @@ package li.cil.oc.server.machine.luac import li.cil.oc.api.network.Component import li.cil.oc.util.ExtendedLuaState.extendLuaState -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ class ComponentAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { def initialize() { diff --git a/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala b/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala index 6404f85b33..40d66a2aa3 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/ComputerAPI.scala @@ -7,7 +7,7 @@ import li.cil.oc.api.driver.item.Processor import li.cil.oc.api.network.Connector import li.cil.oc.util.ExtendedLuaState.extendLuaState -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ class ComputerAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { def initialize() { diff --git a/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala b/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala index 9cf0302a69..80180a6bf7 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/LuaStateFactory.scala @@ -15,7 +15,6 @@ import li.cil.oc.api.machine.Architecture import li.cil.oc.server.machine.Machine import li.cil.oc.util.ExtendedLuaState._ import li.cil.repack.com.naef.jnlua -import li.cil.repack.com.naef.jnlua.NativeSupport.Loader import net.minecraft.item.ItemStack import org.apache.commons.lang3.SystemUtils @@ -53,7 +52,7 @@ object LuaStateFactory { } object Lua52 extends LuaStateFactory { - override def version: String = "lua52" + override def version: String = "52" override protected def create(maxMemory: Option[Int]) = maxMemory.fold(new jnlua.LuaState())(new jnlua.LuaState(_)) @@ -71,7 +70,7 @@ object LuaStateFactory { } object Lua53 extends LuaStateFactory { - override def version: String = "lua53" + override def version: String = "53" override protected def create(maxMemory: Option[Int]) = maxMemory.fold(new jnlua.LuaStateFiveThree())(new jnlua.LuaStateFiveThree(_)) @@ -111,35 +110,39 @@ abstract class LuaStateFactory { private val libraryName = { if (!Strings.isNullOrEmpty(Settings.get.forceNativeLib)) Settings.get.forceNativeLib + else { + val libExtension = { + if (SystemUtils.IS_OS_MAC) ".dylib" + else if (SystemUtils.IS_OS_WINDOWS) ".dll" + else ".so" + } - else if (SystemUtils.IS_OS_FREE_BSD && Architecture.IS_OS_X64) "native.64.bsd.so" - else if (SystemUtils.IS_OS_FREE_BSD && Architecture.IS_OS_X86) "native.32.bsd.so" - - else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_ARM) "native.32.arm.so" - else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_X64) "native.64.so" - else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_X86) "native.32.so" - - else if (SystemUtils.IS_OS_MAC && Architecture.IS_OS_X64) "native.64.dylib" - else if (SystemUtils.IS_OS_MAC && Architecture.IS_OS_X86) "native.32.dylib" + val platformName = { + val systemName = { + if (SystemUtils.IS_OS_FREE_BSD) "freebsd" + else if (SystemUtils.IS_OS_NET_BSD) "netbsd" + else if (SystemUtils.IS_OS_OPEN_BSD) "openbsd" + else if (SystemUtils.IS_OS_SOLARIS) "solaris" + else if (SystemUtils.IS_OS_LINUX) "linux" + else if (SystemUtils.IS_OS_MAC) "darwin" + else if (SystemUtils.IS_OS_WINDOWS) "windows" + else "unknown" + } - else if (SystemUtils.IS_OS_WINDOWS && Architecture.IS_OS_X64) "native.64.dll" - else if (SystemUtils.IS_OS_WINDOWS && Architecture.IS_OS_X86) "native.32.dll" + val archName = { + if (Architecture.IS_OS_ARM64) "aarch64" + else if (Architecture.IS_OS_ARM) "arm" + else if (Architecture.IS_OS_X64) "x86_64" + else if (Architecture.IS_OS_X86) "x86" + else "unknown" + } - else null - } + systemName + "-" + archName + } - // Register a custom library loader with JNLua. We have to trigger - // library loads through JNLua to ensure the LuaState class is the - // one loading the library and not the other way around - the native - // library also references the LuaState class, and if it is loaded - // that way, it will fail to access native methods in its static - // initializer, because the native lib will not have been completely - // loaded at the time the initializer runs. - private def prepareLoad(lib: String): Unit = jnlua.NativeSupport.getInstance().setLoader(new Loader { - def load(): Unit = { - System.load(lib) + "libjnlua" + version + "-" + platformName + libExtension } - }) + } protected def create(maxMemory: Option[Int] = None): jnlua.LuaState @@ -173,13 +176,13 @@ abstract class LuaStateFactory { } } - val libraryUrl = classOf[Machine].getResource(s"/assets/${Settings.resourceDomain}/lib/$version/$libraryName") + val libraryUrl = classOf[Machine].getResource(s"/assets/${Settings.resourceDomain}/lib//$libraryName") if (libraryUrl == null) { OpenComputers.log.warn(s"Native library with name '$version/$libraryName' not found.") return } - val tmpLibName = s"OpenComputersMod-${OpenComputers.Version}-$version-$libraryName" + val tmpLibName = s"OpenComputersMod-${OpenComputers.get.Version}-$version-$libraryName" val tmpBasePath = if (Settings.get.nativeInTmpDir) { val path = System.getProperty("java.io.tmpdir") if (path == null) "" @@ -277,7 +280,7 @@ abstract class LuaStateFactory { currentLib = tmpLibFile.getAbsolutePath try { LuaStateFactory.synchronized { - prepareLoad(currentLib) + System.load(currentLib) create().close() } OpenComputers.log.info(s"Found a compatible native library: '${tmpLibFile.getName}'.") @@ -310,7 +313,7 @@ abstract class LuaStateFactory { try { val state = LuaStateFactory.synchronized { - prepareLoad(currentLib) + System.load(currentLib) if (Settings.get.limitMemory) create(Some(Int.MaxValue)) else create() } @@ -376,7 +379,7 @@ abstract class LuaStateFactory { state.setField(-2, "random") state.pushScalaFunction(lua => { - random.setSeed(lua.checkNumber(1).toLong) + random.setSeed(lua.checkInteger(1)) 0 }) state.setField(-2, "randomseed") @@ -409,6 +412,8 @@ abstract class LuaStateFactory { val IS_OS_ARM = isOSArchMatch("arm") + val IS_OS_ARM64 = isOSArchMatch("aarch64") + val IS_OS_X86 = isOSArchMatch("x86") || isOSArchMatch("i386") val IS_OS_X64 = isOSArchMatch("x86_64") || isOSArchMatch("amd64") diff --git a/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala index f87d313d1d..be3d7e9dca 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/NativeLuaArchitecture.scala @@ -16,9 +16,9 @@ import li.cil.oc.server.machine.Machine import li.cil.oc.util.ExtendedLuaState.extendLuaState import li.cil.repack.com.naef.jnlua._ import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ @Architecture.Name("Lua 5.2") class NativeLua52Architecture(machine: api.machine.Machine) extends NativeLuaArchitecture(machine) { @@ -340,7 +340,7 @@ abstract class NativeLuaArchitecture(val machine: api.machine.Machine) extends A @Deprecated private def state = machine.asInstanceOf[Machine].state - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { if (!machine.isRunning) return // Unlimit memory use while unpersisting. @@ -368,10 +368,10 @@ abstract class NativeLuaArchitecture(val machine: api.machine.Machine) extends A } } - kernelMemory = (nbt.getInteger("kernelMemory") * ramScale).toInt + kernelMemory = (nbt.getInt("kernelMemory") * ramScale).toInt for (api <- apis) { - api.load(nbt) + api.loadData(nbt) } try lua.gc(LuaState.GcAction.COLLECT, 0) catch { @@ -387,7 +387,7 @@ abstract class NativeLuaArchitecture(val machine: api.machine.Machine) extends A recomputeMemory(machine.host.internalComponents) } - override def save(nbt: NBTTagCompound) { + override def saveData(nbt: CompoundNBT) { // Unlimit memory while persisting. if (Settings.get.limitMemory) { lua.setTotalMemory(Integer.MAX_VALUE) @@ -406,10 +406,10 @@ abstract class NativeLuaArchitecture(val machine: api.machine.Machine) extends A SaveHandler.scheduleSave(machine.host, nbt, machine.node.address + "_stack", persistence.persist(2)) } - nbt.setInteger("kernelMemory", math.ceil(kernelMemory / ramScale).toInt) + nbt.putInt("kernelMemory", math.ceil(kernelMemory / ramScale).toInt) for (api <- apis) { - api.save(nbt) + api.saveData(nbt) } try lua.gc(LuaState.GcAction.COLLECT, 0) catch { @@ -420,10 +420,10 @@ abstract class NativeLuaArchitecture(val machine: api.machine.Machine) extends A } catch { case e: LuaRuntimeException => OpenComputers.log.warn(s"Could not persist computer @ (${machine.host.xPosition}, ${machine.host.yPosition}, ${machine.host.zPosition}).\n${e.toString}" + (if (e.getLuaStackTrace.isEmpty) "" else "\tat " + e.getLuaStackTrace.mkString("\n\tat "))) - nbt.removeTag("state") + nbt.remove("state") case e: LuaGcMetamethodException => OpenComputers.log.warn(s"Could not persist computer @ (${machine.host.xPosition}, ${machine.host.yPosition}, ${machine.host.zPosition}).\n${e.toString}") - nbt.removeTag("state") + nbt.remove("state") } // Limit memory again. diff --git a/src/main/scala/li/cil/oc/server/machine/luac/OSAPI.scala b/src/main/scala/li/cil/oc/server/machine/luac/OSAPI.scala index 50d9cba2f7..49e0b60701 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/OSAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/OSAPI.scala @@ -80,7 +80,7 @@ class OSAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { if (res == null) if (d < 0) throw new Exception("field '" + key + "' missing in date table") else d - else res: Int + else res.intValue() } lua.checkType(1, LuaType.TABLE) diff --git a/src/main/scala/li/cil/oc/server/machine/luac/PersistenceAPI.scala b/src/main/scala/li/cil/oc/server/machine/luac/PersistenceAPI.scala index a47f5a95af..2645b19632 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/PersistenceAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/PersistenceAPI.scala @@ -5,7 +5,7 @@ import java.util.UUID import li.cil.oc.Settings import li.cil.oc.util.ExtendedLuaState._ import li.cil.repack.com.naef.jnlua.LuaState -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT import scala.collection.mutable @@ -85,21 +85,21 @@ class PersistenceAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { lua.getGlobal("_G") /* ... perms uperms k v */ flattenAndStore() /* ... perms uperms */ - lua.setField(LuaState.REGISTRYINDEX, "uperms") /* ... perms */ - lua.setField(LuaState.REGISTRYINDEX, "perms") /* ... */ + lua.setField(lua.getRegistryIndex, "uperms") /* ... perms */ + lua.setField(lua.getRegistryIndex, "perms") /* ... */ } } - override def load(nbt: NBTTagCompound) { - super.load(nbt) - if (nbt.hasKey("persistKey")) { + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + if (nbt.contains("persistKey")) { persistKey = nbt.getString("persistKey") } } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setString("persistKey", persistKey) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putString("persistKey", persistKey) } def configure() { @@ -126,7 +126,7 @@ class PersistenceAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { lua.getGlobal("eris") // ... eris lua.getField(-1, "persist") // ... eris persist if (lua.isFunction(-1)) { - lua.getField(LuaState.REGISTRYINDEX, "perms") // ... eris persist perms + lua.getField(lua.getRegistryIndex, "perms") // ... eris persist perms lua.pushValue(index) // ... eris persist perms obj try { lua.call(2, 1) // ... eris str? @@ -159,7 +159,7 @@ class PersistenceAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { lua.getGlobal("eris") // ... eris lua.getField(-1, "unpersist") // ... eris unpersist if (lua.isFunction(-1)) { - lua.getField(LuaState.REGISTRYINDEX, "uperms") // ... eris persist uperms + lua.getField(lua.getRegistryIndex, "uperms") // ... eris persist uperms lua.pushByteArray(value) // ... eris unpersist uperms str lua.call(2, 1) // ... eris obj lua.insert(-2) // ... obj eris diff --git a/src/main/scala/li/cil/oc/server/machine/luac/UnicodeAPI.scala b/src/main/scala/li/cil/oc/server/machine/luac/UnicodeAPI.scala index c327815c4a..081c7de7a0 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/UnicodeAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/UnicodeAPI.scala @@ -9,7 +9,7 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { lua.newTable() lua.pushScalaFunction(lua => { - lua.pushString(String.valueOf((1 to lua.getTop).map(lua.checkInteger).map(_.toChar).toArray)) + lua.pushString(String.valueOf((1 to lua.getTop).map(lua.checkInt32).map(_.toChar).toArray)) 1 }) lua.setField(-2, "char") @@ -34,12 +34,12 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { lua.pushScalaFunction(lua => { val string = lua.checkString(1) - val start = math.max(0, lua.checkInteger(2) match { + val start = math.max(0, lua.checkInt32(2) match { case i if i < 0 => string.length + i case i => i - 1 }) val end = - if (lua.getTop > 2) math.min(string.length, lua.checkInteger(3) match { + if (lua.getTop > 2) math.min(string.length, lua.checkInt32(3) match { case i if i < 0 => string.length + i + 1 case i => i }) diff --git a/src/main/scala/li/cil/oc/server/machine/luac/UserdataAPI.scala b/src/main/scala/li/cil/oc/server/machine/luac/UserdataAPI.scala index 3d24fe65e0..ddc04a1dbf 100644 --- a/src/main/scala/li/cil/oc/server/machine/luac/UserdataAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luac/UserdataAPI.scala @@ -12,19 +12,19 @@ import li.cil.oc.server.driver.Registry import li.cil.oc.server.machine.ArgumentsImpl import li.cil.oc.util.ExtendedLuaState.extendLuaState import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ class UserdataAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { def initialize() { lua.newTable() lua.pushScalaFunction(lua => { - val nbt = new NBTTagCompound() + val nbt = new CompoundNBT() val persistable = lua.toJavaObjectRaw(1).asInstanceOf[Persistable] lua.pushString(persistable.getClass.getName) - persistable.save(nbt) + persistable.saveData(nbt) val baos = new ByteArrayOutputStream() val dos = new DataOutputStream(baos) CompressedStreamTools.write(nbt, dos) @@ -42,7 +42,7 @@ class UserdataAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) { val bais = new ByteArrayInputStream(data) val dis = new DataInputStream(bais) val nbt = CompressedStreamTools.read(dis) - persistable.load(nbt) + persistable.loadData(nbt) lua.pushJavaObjectRaw(persistable) 1 } diff --git a/src/main/scala/li/cil/oc/server/machine/luaj/ComponentAPI.scala b/src/main/scala/li/cil/oc/server/machine/luaj/ComponentAPI.scala index 8dfe93e412..3a94886355 100644 --- a/src/main/scala/li/cil/oc/server/machine/luaj/ComponentAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luaj/ComponentAPI.scala @@ -5,7 +5,7 @@ import li.cil.oc.util.ScalaClosure._ import li.cil.repack.org.luaj.vm2.LuaValue import li.cil.repack.org.luaj.vm2.Varargs -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ class ComponentAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) { override def initialize() { diff --git a/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala b/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala index 874c6a43cf..ecd43992c5 100644 --- a/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luaj/ComputerAPI.scala @@ -9,7 +9,7 @@ import li.cil.oc.util.ScalaClosure._ import li.cil.repack.org.luaj.vm2.LuaValue import li.cil.repack.org.luaj.vm2.Varargs -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ class ComputerAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) { override def initialize() { diff --git a/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala index 2c8b2388b7..202b3c6522 100644 --- a/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/machine/luaj/LuaJLuaArchitecture.scala @@ -17,9 +17,9 @@ import li.cil.oc.util.ScalaClosure._ import li.cil.repack.org.luaj.vm2._ import li.cil.repack.org.luaj.vm2.lib.jse.JsePlatform import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ @Architecture.Name("LuaJ") class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture { @@ -250,12 +250,12 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { if (machine.isRunning) { machine.stop() machine.start() } } - override def save(nbt: NBTTagCompound) {} + override def saveData(nbt: CompoundNBT) {} } diff --git a/src/main/scala/li/cil/oc/server/machine/luaj/UserdataAPI.scala b/src/main/scala/li/cil/oc/server/machine/luaj/UserdataAPI.scala index 336fc4eea5..187733fb9c 100644 --- a/src/main/scala/li/cil/oc/server/machine/luaj/UserdataAPI.scala +++ b/src/main/scala/li/cil/oc/server/machine/luaj/UserdataAPI.scala @@ -8,7 +8,7 @@ import li.cil.oc.util.ScalaClosure._ import li.cil.repack.org.luaj.vm2.LuaValue import li.cil.repack.org.luaj.vm2.Varargs -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ class UserdataAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) { override def initialize() { diff --git a/src/main/scala/li/cil/oc/server/network/Component.scala b/src/main/scala/li/cil/oc/server/network/Component.scala index 086888ef59..53954d2c00 100644 --- a/src/main/scala/li/cil/oc/server/network/Component.scala +++ b/src/main/scala/li/cil/oc/server/network/Component.scala @@ -7,16 +7,17 @@ import li.cil.oc.api.network.{Node => ImmutableNode} import li.cil.oc.common.item.data.NodeData import li.cil.oc.server.driver.CompoundBlockEnvironment import li.cil.oc.server.driver.Registry +import li.cil.oc.server.network.Node import li.cil.oc.server.machine.ArgumentsImpl import li.cil.oc.server.machine.Callbacks import li.cil.oc.server.machine.Callbacks.ComponentCallback import li.cil.oc.server.machine.Callbacks.PeripheralCallback import li.cil.oc.server.machine.Machine import li.cil.oc.util.SideTracker -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ trait Component extends network.Component with Node { def visibility = _visibility @@ -118,16 +119,16 @@ trait Component extends network.Component with Node { // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { - super.load(nbt) - if (nbt.hasKey(NodeData.VisibilityTag)) { - _visibility = Visibility.values()(nbt.getInteger(NodeData.VisibilityTag)) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) + if (nbt.contains(NodeData.VisibilityTag)) { + _visibility = Visibility.values()(nbt.getInt(NodeData.VisibilityTag)) } } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setInteger(NodeData.VisibilityTag, _visibility.ordinal()) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putInt(NodeData.VisibilityTag, _visibility.ordinal()) } override def toString = super.toString + s"@$name" diff --git a/src/main/scala/li/cil/oc/server/network/Connector.scala b/src/main/scala/li/cil/oc/server/network/Connector.scala index 8b905f74dd..7311408dd0 100644 --- a/src/main/scala/li/cil/oc/server/network/Connector.scala +++ b/src/main/scala/li/cil/oc/server/network/Connector.scala @@ -4,7 +4,7 @@ import li.cil.oc.Settings import li.cil.oc.api.network import li.cil.oc.api.network.{Node => ImmutableNode} import li.cil.oc.common.item.data.NodeData -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT trait Connector extends network.Connector with Node { var localBufferSize = 0.0 @@ -113,19 +113,19 @@ trait Connector extends network.Connector with Node { override def onDisconnect(node: ImmutableNode) { super.onDisconnect(node) if (node == this) { - this.synchronized(distributor = None) + this.synchronized(this.distributor = None) } } // ----------------------------------------------------------------------- // - override def load(nbt: NBTTagCompound) { - super.load(nbt) + override def loadData(nbt: CompoundNBT) { + super.loadData(nbt) localBuffer = nbt.getDouble(NodeData.BufferTag) } - override def save(nbt: NBTTagCompound) { - super.save(nbt) - nbt.setDouble(NodeData.BufferTag, math.min(localBuffer, localBufferSize)) + override def saveData(nbt: CompoundNBT) { + super.saveData(nbt) + nbt.putDouble(NodeData.BufferTag, math.min(localBuffer, localBufferSize)) } } diff --git a/src/main/scala/li/cil/oc/server/network/DebugNetwork.scala b/src/main/scala/li/cil/oc/server/network/DebugNetwork.scala index 4702e7fcae..d7454c6f29 100644 --- a/src/main/scala/li/cil/oc/server/network/DebugNetwork.scala +++ b/src/main/scala/li/cil/oc/server/network/DebugNetwork.scala @@ -8,7 +8,7 @@ object DebugNetwork { val cards = mutable.WeakHashMap.empty[DebugNode, Unit] def add(card: DebugNode) { - cards.put(card, Unit) + cards.put(card, ()) } def remove(card: DebugNode) { diff --git a/src/main/scala/li/cil/oc/server/network/Network.scala b/src/main/scala/li/cil/oc/server/network/Network.scala index 3ab2c46055..160e370cc5 100644 --- a/src/main/scala/li/cil/oc/server/network/Network.scala +++ b/src/main/scala/li/cil/oc/server/network/Network.scala @@ -8,15 +8,21 @@ import li.cil.oc.api.network._ import li.cil.oc.api.network.{Node => ImmutableNode} import li.cil.oc.common.capabilities.Capabilities import li.cil.oc.common.tileentity +import li.cil.oc.server.network.Component +import li.cil.oc.server.network.ComponentConnector +import li.cil.oc.server.network.Connector import li.cil.oc.server.network.{Node => MutableNode} import li.cil.oc.util.Color +import li.cil.oc.util.ResultWrapper import li.cil.oc.util.SideTracker -import net.minecraft.item.EnumDyeColor +import net.minecraft.item.DyeColor import net.minecraft.nbt._ import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.RegistryKey import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IBlockReader +import net.minecraft.world.World import scala.collection.JavaConverters._ import scala.collection.mutable @@ -442,14 +448,14 @@ private class Network private(private val data: mutable.Map[String, Network.Vert } object Network extends api.detail.NetworkAPI { - override def joinOrCreateNetwork(world: IBlockAccess, pos: BlockPos): Unit = { - val tileEntity = world.getTileEntity(pos) - if (tileEntity != null && !tileEntity.isInvalid && tileEntity.getWorld != null && !tileEntity.getWorld.isRemote) { - for (side <- EnumFacing.values) { - val npos = tileEntity.getPos.offset(side) - if (tileEntity.getWorld.isBlockLoaded(npos)) { + override def joinOrCreateNetwork(world: IBlockReader, pos: BlockPos): Unit = { + val tileEntity = world.getBlockEntity(pos) + if (tileEntity != null && !tileEntity.isRemoved && tileEntity.getLevel != null && !tileEntity.getLevel.isClientSide) { + for (side <- Direction.values) { + val npos = tileEntity.getBlockPos.relative(side) + if (tileEntity.getLevel.isLoaded(npos)) { val localNode = getNetworkNode(tileEntity, side) - val neighborTileEntity = tileEntity.getWorld.getTileEntity(npos) + val neighborTileEntity = tileEntity.getLevel.getBlockEntity(npos) val neighborNode = getNetworkNode(neighborTileEntity, side.getOpposite) localNode match { case Some(node: MutableNode) => @@ -473,8 +479,8 @@ object Network extends api.detail.NetworkAPI { override def joinOrCreateNetwork(tileEntity: TileEntity): Unit = { if (tileEntity != null) { - val world = tileEntity.getWorld - val pos = tileEntity.getPos + val world = tileEntity.getLevel + val pos = tileEntity.getBlockPos if (world != null && pos != null) { joinOrCreateNetwork(world, pos) } @@ -487,15 +493,15 @@ object Network extends api.detail.NetworkAPI { case _ => } - def getNetworkNode(tileEntity: TileEntity, side: EnumFacing): Option[ImmutableNode] = { + def getNetworkNode(tileEntity: TileEntity, side: Direction): Option[ImmutableNode] = { if (tileEntity != null) { - if (tileEntity.hasCapability(Capabilities.SidedEnvironmentCapability, side)) { - val host = tileEntity.getCapability(Capabilities.SidedEnvironmentCapability, side) + if (tileEntity.getCapability(Capabilities.SidedEnvironmentCapability, side).isPresent) { + val host = tileEntity.getCapability(Capabilities.SidedEnvironmentCapability, side).orElse(null) if (host != null) return Option(host.sidedNode(side)) } - if (tileEntity.hasCapability(Capabilities.EnvironmentCapability, side)) { - val host = tileEntity.getCapability(Capabilities.EnvironmentCapability, side) + if (tileEntity.getCapability(Capabilities.EnvironmentCapability, side).isPresent) { + val host = tileEntity.getCapability(Capabilities.EnvironmentCapability, side).orElse(null) if (host != null) return Option(host.node) } } @@ -505,21 +511,21 @@ object Network extends api.detail.NetworkAPI { private def getConnectionColor(tileEntity: TileEntity): Int = { if (tileEntity != null) { - if (tileEntity.hasCapability(Capabilities.ColoredCapability, null)) { - val colored = tileEntity.getCapability(Capabilities.ColoredCapability, null) + if (tileEntity.getCapability(Capabilities.ColoredCapability, null).isPresent) { + val colored = tileEntity.getCapability(Capabilities.ColoredCapability, null).orElse(null) if (colored != null && colored.controlsConnectivity) return colored.getColor } } - Color.rgbValues(EnumDyeColor.SILVER) + Color.rgbValues(DyeColor.LIGHT_GRAY) } private def canConnectBasedOnColor(te1: TileEntity, te2: TileEntity) = { val (c1, c2) = (getConnectionColor(te1), getConnectionColor(te2)) - c1 == c2 || c1 == Color.rgbValues(EnumDyeColor.SILVER) || c2 == Color.rgbValues(EnumDyeColor.SILVER) + c1 == c2 || c1 == Color.rgbValues(DyeColor.LIGHT_GRAY) || c2 == Color.rgbValues(DyeColor.LIGHT_GRAY) } - private def canConnectFromSideIM(tileEntity: TileEntity, side: EnumFacing) = + private def canConnectFromSideIM(tileEntity: TileEntity, side: Direction) = tileEntity match { case im: tileentity.traits.ImmibisMicroblock => im.ImmibisMicroblocks_isSideOpen(side.ordinal) case _ => true @@ -539,7 +545,7 @@ object Network extends api.detail.NetworkAPI { WirelessNetwork.remove(endpoint) } - override def leaveWirelessNetwork(endpoint: WirelessEndpoint, dimension: Int) { + override def leaveWirelessNetwork(endpoint: WirelessEndpoint, dimension: RegistryKey[World]) { WirelessNetwork.remove(endpoint, dimension) } @@ -565,21 +571,21 @@ object Network extends api.detail.NetworkAPI { packet } - override def newPacket(nbt: NBTTagCompound) = { + override def newPacket(nbt: CompoundNBT) = { val source = nbt.getString("source") val destination = - if (nbt.hasKey("dest")) null + if (nbt.contains("dest")) null else nbt.getString("dest") - val port = nbt.getInteger("port") - val ttl = nbt.getInteger("ttl") - val data = (for (i <- 0 until nbt.getInteger("dataLength")) yield { - if (nbt.hasKey("data" + i)) { - nbt.getTag("data" + i) match { - case tag: NBTTagByte => Boolean.box(tag.getByte == 1) - case tag: NBTTagInt => Int.box(tag.getInt) - case tag: NBTTagDouble => Double.box(tag.getDouble) - case tag: NBTTagString => tag.getString: AnyRef - case tag: NBTTagByteArray => tag.getByteArray + val port = nbt.getInt("port") + val ttl = nbt.getInt("ttl") + val data = (for (i <- 0 until nbt.getInt("dataLength")) yield { + if (nbt.contains("data" + i)) { + nbt.get("data" + i) match { + case tag: ByteNBT => Boolean.box(tag.getAsByte == 1) + case tag: IntNBT => Int.box(tag.getAsInt) + case tag: DoubleNBT => Double.box(tag.getAsDouble) + case tag: StringNBT => tag.getAsString: AnyRef + case tag: ByteArrayNBT => tag.getAsByteArray } } else null @@ -650,7 +656,7 @@ object Network extends api.detail.NetworkAPI { def remove() = { edges.foreach(edge => edge.other(this).edges -= edge) - searchGraphs(edges.map(_.other(this))) + searchGraphs(edges.map(_.other(this)).toSeq) } override def toString = s"$data [${edges.length}]" @@ -706,7 +712,7 @@ object Network extends api.detail.NetworkAPI { } values.length * 2 + values.foldLeft(0)((acc, arg) => { acc + (arg match { - case null | Unit | None => 4 + case null | ResultWrapper.unit | None => 4 case _: java.lang.Boolean => 4 case _: java.lang.Byte => 4 case _: java.lang.Short => 4 @@ -722,21 +728,21 @@ object Network extends api.detail.NetworkAPI { override def hop() = new Packet(source, destination, port, data, ttl - 1) - override def save(nbt: NBTTagCompound) { - nbt.setString("source", source) + override def saveData(nbt: CompoundNBT) { + nbt.putString("source", source) if (destination != null && !destination.isEmpty) { - nbt.setString("dest", destination) + nbt.putString("dest", destination) } - nbt.setInteger("port", port) - nbt.setInteger("ttl", ttl) - nbt.setInteger("dataLength", data.length) + nbt.putInt("port", port) + nbt.putInt("ttl", ttl) + nbt.putInt("dataLength", data.length) for (i <- data.indices) data(i) match { - case null | Unit | None => - case value: java.lang.Boolean => nbt.setBoolean("data" + i, value) - case value: java.lang.Integer => nbt.setInteger("data" + i, value) - case value: java.lang.Double => nbt.setDouble("data" + i, value) - case value: java.lang.String => nbt.setString("data" + i, value) - case value: Array[Byte] => nbt.setByteArray("data" + i, value) + case null | ResultWrapper.unit | None => + case value: java.lang.Boolean => nbt.putBoolean("data" + i, value) + case value: java.lang.Integer => nbt.putInt("data" + i, value) + case value: java.lang.Double => nbt.putDouble("data" + i, value) + case value: java.lang.String => nbt.putString("data" + i, value) + case value: Array[Byte] => nbt.putByteArray("data" + i, value) case value => OpenComputers.log.warn("Unexpected type while saving network packet: " + value.getClass.getName) } } diff --git a/src/main/scala/li/cil/oc/server/network/Node.scala b/src/main/scala/li/cil/oc/server/network/Node.scala index 6bc30be3eb..37d43594fd 100644 --- a/src/main/scala/li/cil/oc/server/network/Node.scala +++ b/src/main/scala/li/cil/oc/server/network/Node.scala @@ -6,10 +6,10 @@ import li.cil.oc.api import li.cil.oc.api.network.Environment import li.cil.oc.api.network.Visibility import li.cil.oc.api.network.{Node => ImmutableNode} -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ trait Node extends ImmutableNode { def host: Environment @@ -71,8 +71,8 @@ trait Node extends ImmutableNode { // ----------------------------------------------------------------------- // - def load(nbt: NBTTagCompound) = { - if (nbt.hasKey("address")) { + def loadData(nbt: CompoundNBT) { + if (nbt.contains("address")) { val newAddress = nbt.getString("address") if (!Strings.isNullOrEmpty(newAddress) && newAddress != address) network match { case wrapper: Network.Wrapper => wrapper.network.remap(this, newAddress) @@ -81,9 +81,9 @@ trait Node extends ImmutableNode { } } - def save(nbt: NBTTagCompound) = { + def saveData(nbt: CompoundNBT) { if (address != null) { - nbt.setString("address", address) + nbt.putString("address", address) } } diff --git a/src/main/scala/li/cil/oc/server/network/QuantumNetwork.scala b/src/main/scala/li/cil/oc/server/network/QuantumNetwork.scala index 2ea00f3fef..17dca3e5df 100644 --- a/src/main/scala/li/cil/oc/server/network/QuantumNetwork.scala +++ b/src/main/scala/li/cil/oc/server/network/QuantumNetwork.scala @@ -9,7 +9,7 @@ object QuantumNetwork { val tunnels = mutable.Map.empty[String, mutable.WeakHashMap[QuantumNode, Unit]] def add(card: QuantumNode) { - tunnels.getOrElseUpdate(card.tunnel, mutable.WeakHashMap.empty).put(card, Unit) + tunnels.getOrElseUpdate(card.tunnel, mutable.WeakHashMap.empty).put(card, ()) } def remove(card: QuantumNode) { diff --git a/src/main/scala/li/cil/oc/server/network/Waypoints.scala b/src/main/scala/li/cil/oc/server/network/Waypoints.scala index 5ee18be67e..51e4f9064f 100644 --- a/src/main/scala/li/cil/oc/server/network/Waypoints.scala +++ b/src/main/scala/li/cil/oc/server/network/Waypoints.scala @@ -4,44 +4,52 @@ import li.cil.oc.Settings import li.cil.oc.common.tileentity.Waypoint import li.cil.oc.util.BlockPosition import li.cil.oc.util.RTree +import net.minecraft.util.RegistryKey +import net.minecraft.world.World import net.minecraftforge.event.world.ChunkEvent import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object Waypoints { - val dimensions = mutable.Map.empty[Int, RTree[Waypoint]] + val dimensions = mutable.Map.empty[RegistryKey[World], RTree[Waypoint]] @SubscribeEvent def onWorldUnload(e: WorldEvent.Unload) { - if (!e.getWorld.isRemote) { - dimensions.remove(e.getWorld.provider.getDimension) + if (!e.getWorld.isClientSide) { + e.getWorld match { + case world: World => dimensions.remove(world.dimension) + case _ => + } } } @SubscribeEvent def onWorldLoad(e: WorldEvent.Load) { - if (!e.getWorld.isRemote) { - dimensions.remove(e.getWorld.provider.getDimension) + if (!e.getWorld.isClientSide) { + e.getWorld match { + case world: World => dimensions.remove(world.dimension) + case _ => + } } } // Safety clean up, in case some tile entities didn't properly leave the net. @SubscribeEvent - def onChunkUnload(e: ChunkEvent.Unload) { - e.getChunk.getTileEntityMap.values.foreach { + def onChunkUnloaded(e: ChunkEvent.Unload) { + e.getChunk.getBlockEntitiesPos.map(e.getChunk.getBlockEntity).foreach { case waypoint: Waypoint => remove(waypoint) case _ => } } - def add(waypoint: Waypoint): Unit = if (!waypoint.isInvalid && waypoint.world != null && !waypoint.world.isRemote) { + def add(waypoint: Waypoint): Unit = if (!waypoint.isRemoved && waypoint.world != null && !waypoint.world.isClientSide) { dimensions.getOrElseUpdate(dimension(waypoint), new RTree[Waypoint](Settings.get.rTreeMaxEntries)((waypoint) => (waypoint.x + 0.5, waypoint.y + 0.5, waypoint.z + 0.5))).add(waypoint) } - def remove(waypoint: Waypoint): Unit = if (waypoint.world != null && !waypoint.world.isRemote) { + def remove(waypoint: Waypoint): Unit = if (waypoint.world != null && !waypoint.world.isClientSide) { dimensions.get(dimension(waypoint)) match { case Some(set) => set.remove(waypoint) case _ => @@ -49,13 +57,13 @@ object Waypoints { } def findWaypoints(pos: BlockPosition, range: Double): Iterable[Waypoint] = { - dimensions.get(pos.world.get.provider.getDimension) match { + dimensions.get(pos.world.get.dimension) match { case Some(set) => - val bounds = pos.bounds.grow(range * 0.5, range * 0.5, range * 0.5) + val bounds = pos.bounds.inflate(range * 0.5, range * 0.5, range * 0.5) set.query((bounds.minX, bounds.minY, bounds.minZ), (bounds.maxX, bounds.maxY, bounds.maxZ)) case _ => Iterable.empty } } - private def dimension(waypoint: Waypoint) = waypoint.world.provider.getDimension + private def dimension(waypoint: Waypoint) = waypoint.world.dimension } diff --git a/src/main/scala/li/cil/oc/server/network/WirelessNetwork.scala b/src/main/scala/li/cil/oc/server/network/WirelessNetwork.scala index ad9b3707f9..97e7fc2a69 100644 --- a/src/main/scala/li/cil/oc/server/network/WirelessNetwork.scala +++ b/src/main/scala/li/cil/oc/server/network/WirelessNetwork.scala @@ -6,35 +6,39 @@ import li.cil.oc.util.BlockPosition import li.cil.oc.util.ExtendedBlock._ import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.RTree -import net.minecraft.util.math.Vec3d +import net.minecraft.util.RegistryKey +import net.minecraft.util.math.vector.Vector3d +import net.minecraft.world.World import net.minecraftforge.event.world.ChunkEvent import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.eventbus.api.SubscribeEvent -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object WirelessNetwork { - val dimensions = mutable.Map.empty[Int, RTree[WirelessEndpoint]] + val dimensions = mutable.Map.empty[RegistryKey[World], RTree[WirelessEndpoint]] @SubscribeEvent def onWorldUnload(e: WorldEvent.Unload) { - if (!e.getWorld.isRemote) { - dimensions.remove(e.getWorld.provider.getDimension) + if (!e.getWorld.isClientSide) e.getWorld match { + case world: World => dimensions.remove(world.dimension) + case _ => } } @SubscribeEvent def onWorldLoad(e: WorldEvent.Load) { - if (!e.getWorld.isRemote) { - dimensions.remove(e.getWorld.provider.getDimension) + if (!e.getWorld.isClientSide) e.getWorld match { + case world: World => dimensions.remove(world.dimension) + case _ => } } // Safety clean up, in case some tile entities didn't properly leave the net. @SubscribeEvent - def onChunkUnload(e: ChunkEvent.Unload) { - e.getChunk.getTileEntityMap.values.foreach { + def onChunkUnloaded(e: ChunkEvent.Unload) { + e.getChunk.getBlockEntitiesPos.map(e.getChunk.getBlockEntity).foreach { case endpoint: WirelessEndpoint => remove(endpoint) case _ => } @@ -62,7 +66,7 @@ object WirelessNetwork { } } - def remove(endpoint: WirelessEndpoint, dimension: Int) = { + def remove(endpoint: WirelessEndpoint, dimension: RegistryKey[World]) = { dimensions.get(dimension) match { case Some(set) => set.remove(endpoint) case _ => false @@ -91,7 +95,7 @@ object WirelessNetwork { } } - private def dimension(endpoint: WirelessEndpoint) = endpoint.world.provider.getDimension + private def dimension(endpoint: WirelessEndpoint) = endpoint.world.dimension private def offset(endpoint: WirelessEndpoint, value: Double) = (endpoint.x + 0.5 + value, endpoint.y + 0.5 + value, endpoint.z + 0.5 + value) @@ -117,8 +121,8 @@ object WirelessNetwork { // the message. val world = endpoint.world - val origin = new Vec3d(reference.x, reference.y, reference.z) - val target = new Vec3d(endpoint.x, endpoint.y, endpoint.z) + val origin = new Vector3d(reference.x, reference.y, reference.z) + val target = new Vector3d(endpoint.x, endpoint.y, endpoint.z) // Vector from reference endpoint (sender) to this one (receiver). val delta = subtract(target, origin) @@ -127,10 +131,10 @@ object WirelessNetwork { // Get the vectors that are orthogonal to the direction vector. val up = if (v.x == 0 && v.z == 0) { assert(v.y != 0) - new Vec3d(1, 0, 0) + new Vector3d(1, 0, 0) } else { - new Vec3d(0, 1, 0) + new Vector3d(0, 1, 0) } val side = crossProduct(v, up) val top = crossProduct(v, side) @@ -140,16 +144,16 @@ object WirelessNetwork { val samples = math.max(1, math.sqrt(gap).toInt) for (i <- 0 until samples) { - val rGap = world.rand.nextDouble() * gap + val rGap = world.random.nextDouble() * gap // Adding some jitter to avoid only tracking the perfect line between // two endpoints when they are diagonal to each other for example. - val rSide = world.rand.nextInt(3) - 1 - val rTop = world.rand.nextInt(3) - 1 + val rSide = world.random.nextInt(3) - 1 + val rTop = world.random.nextInt(3) - 1 val x = (origin.x + v.x * rGap + side.x * rSide + top.x * rTop).toInt val y = (origin.y + v.y * rGap + side.y * rSide + top.y * rTop).toInt val z = (origin.z + v.z * rGap + side.z * rSide + top.z * rTop).toInt val blockPos = BlockPosition(x, y, z, world) - if (world.isBlockLoaded(blockPos)) Option(world.getBlock(blockPos)) match { + if (world.isLoaded(blockPos)) Option(world.getBlock(blockPos)) match { case Some(block) => hardness += block.getBlockHardness(blockPos) case _ => } @@ -164,7 +168,7 @@ object WirelessNetwork { else true } - private def subtract(v1: Vec3d, v2: Vec3d) = new Vec3d(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) + private def subtract(v1: Vector3d, v2: Vector3d) = new Vector3d(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z) - private def crossProduct(v1: Vec3d, v2: Vec3d) = new Vec3d(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x) + private def crossProduct(v1: Vector3d, v2: Vector3d) = new Vector3d(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x) } diff --git a/src/main/scala/li/cil/oc/util/Audio.scala b/src/main/scala/li/cil/oc/util/Audio.scala index 14e6cc969c..1281a520a2 100644 --- a/src/main/scala/li/cil/oc/util/Audio.scala +++ b/src/main/scala/li/cil/oc/util/Audio.scala @@ -5,19 +5,17 @@ import java.nio.ByteBuffer import li.cil.oc.OpenComputers import li.cil.oc.Settings import net.minecraft.client.Minecraft -import net.minecraft.client.audio.PositionedSoundRecord -import net.minecraft.init.SoundEvents +import net.minecraft.client.audio.SimpleSound +import net.minecraft.util.SoundEvents import net.minecraft.util.ResourceLocation import net.minecraft.util.SoundCategory import net.minecraft.util.SoundEvent import net.minecraft.util.math.BlockPos -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent +import net.minecraft.util.math.vector.Vector3d +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.event.TickEvent.ClientTickEvent import org.lwjgl.BufferUtils -import org.lwjgl.openal.AL import org.lwjgl.openal.AL10 -import org.lwjgl.openal.OpenALException import scala.collection.mutable @@ -37,7 +35,7 @@ object Audio { private val sources = mutable.Set.empty[Source] - private def volume = Minecraft.getMinecraft.gameSettings.getSoundLevel(SoundCategory.BLOCKS) + private def volume = Minecraft.getInstance.options.getSoundSourceVolume(SoundCategory.BLOCKS) private var disableAudio = false @@ -46,8 +44,8 @@ object Audio { } def play(x: Float, y: Float, z: Float, pattern: String, frequencyInHz: Int = 1000, durationInMilliseconds: Int = 200): Unit = { - val mc = Minecraft.getMinecraft - val distanceBasedGain = math.max(0, 1 - mc.player.getDistance(x, y, z) / maxDistance).toFloat + val mc = Minecraft.getInstance + val distanceBasedGain = math.max(0, 1 - mc.player.position.distanceTo(new Vector3d(x, y, z)) / maxDistance).toFloat val gain = distanceBasedGain * volume if (gain <= 0 || amplitude <= 0) return @@ -61,54 +59,52 @@ object Audio { val clampedFrequency = ((frequencyInHz - 20) max 0 min 1980) / 1980f + 0.5f var delay = 0 for (ch <- pattern) { - val record = new PositionedSoundRecord(SoundEvents.BLOCK_NOTE_HARP, SoundCategory.BLOCKS, gain, clampedFrequency, new BlockPos(x, y, z)) - if (delay == 0) mc.getSoundHandler.playSound(record) - else mc.getSoundHandler.playDelayedSound(record, delay) + val record = new SimpleSound(SoundEvents.NOTE_BLOCK_HARP, SoundCategory.BLOCKS, gain, clampedFrequency, new BlockPos(x, y, z)) + if (delay == 0) mc.getSoundManager.play(record) + else mc.getSoundManager.playDelayed(record, delay) delay += ((if (ch == '.') durationInMilliseconds else 2 * durationInMilliseconds) * 20 / 1000) max 1 } } else { - if (AL.isCreated) { - val sampleCounts = pattern.toCharArray. - map(ch => if (ch == '.') durationInMilliseconds else 2 * durationInMilliseconds). - map(_ * sampleRate / 1000) - // 50ms pause between pattern parts. - val pauseSampleCount = 50 * sampleRate / 1000 - val data = BufferUtils.createByteBuffer(sampleCounts.sum + (sampleCounts.length - 1) * pauseSampleCount) - val step = frequencyInHz / sampleRate.toFloat - var offset = 0f - for (sampleCount <- sampleCounts) { - for (sample <- 0 until sampleCount) { - val angle = 2 * math.Pi * offset - val value = (math.signum(math.sin(angle)) * amplitude).toByte ^ 0x80 - offset += step - if (offset > 1) offset -= 1 - data.put(value.toByte) - } - if (data.hasRemaining) { - for (sample <- 0 until pauseSampleCount) { - data.put(127: Byte) - } - } + val sampleCounts = pattern.toCharArray. + map(ch => if (ch == '.') durationInMilliseconds else 2 * durationInMilliseconds). + map(_ * sampleRate / 1000) + // 50ms pause between pattern parts. + val pauseSampleCount = 50 * sampleRate / 1000 + val data = BufferUtils.createByteBuffer(sampleCounts.sum + (sampleCounts.length - 1) * pauseSampleCount) + val step = frequencyInHz / sampleRate.toFloat + var offset = 0f + for (sampleCount <- sampleCounts) { + for (sample <- 0 until sampleCount) { + val angle = 2 * math.Pi * offset + val value = (math.signum(math.sin(angle)) * amplitude).toByte ^ 0x80 + offset += step + if (offset > 1) offset -= 1 + data.put(value.toByte) } - data.rewind() - - // Watch out for sound cards running out of memory... this apparently - // really does happen. I'm assuming this is due to too many sounds being - // kept loaded, since from what I can see OC's releasing its audio - // memory as it should. - try sources.synchronized(sources += new Source(x, y, z, data, gain)) catch { - case e: LessUselessOpenALException => - if (e.errorCode == AL10.AL_OUT_OF_MEMORY) { - // Well... let's just stop here. - OpenComputers.log.info("Couldn't play computer speaker sound because your sound card ran out of memory. Either your sound card is just really low-end, or there are just too many sounds in use already by other mods. Disabling computer speakers to avoid spamming your log file now.") - disableAudio = true - } - else { - OpenComputers.log.warn("Error playing computer speaker sound.", e) - } + if (data.hasRemaining) { + for (sample <- 0 until pauseSampleCount) { + data.put(127: Byte) + } } } + data.rewind() + + // Watch out for sound cards running out of memory... this apparently + // really does happen. I'm assuming this is due to too many sounds being + // kept loaded, since from what I can see OC's releasing its audio + // memory as it should. + try sources.synchronized(sources += new Source(x, y, z, data, gain)) catch { + case e: OpenALException => + if (e.errorCode == AL10.AL_OUT_OF_MEMORY) { + // Well... let's just stop here. + OpenComputers.log.info("Couldn't play computer speaker sound because your sound card ran out of memory. Either your sound card is just really low-end, or there are just too many sounds in use already by other mods. Disabling computer speakers to avoid spamming your log file now.") + disableAudio = true + } + else { + OpenComputers.log.warn("Error playing computer speaker sound.", e) + } + } } } @@ -117,12 +113,10 @@ object Audio { sources.synchronized(sources --= sources.filter(_.checkFinished)) // Clear error stack. - if (AL.isCreated) { - try AL10.alGetError() catch { - case _: UnsatisfiedLinkError => - OpenComputers.log.warn("Negotiations with OpenAL broke down, disabling sounds.") - disableAudio = true - } + try AL10.alGetError() catch { + case _: UnsatisfiedLinkError => + OpenComputers.log.warn("Negotiations with OpenAL broke down, disabling sounds.") + disableAudio = true } } } @@ -178,18 +172,16 @@ object Audio { } // Having the error code in an accessible way is really cool, you know. - class LessUselessOpenALException(val errorCode: Int) extends OpenALException(errorCode) + class OpenALException(val errorCode: Int) extends RuntimeException // Custom implementation of Util.checkALError() that uses our custom exception. def checkALError(): Unit = { val errorCode = AL10.alGetError() if (errorCode != AL10.AL_NO_ERROR) { - throw new LessUselessOpenALException(errorCode) + throw new OpenALException(errorCode) } } - MinecraftForge.EVENT_BUS.register(this) - @SubscribeEvent def onTick(e: ClientTickEvent) { update() diff --git a/src/main/scala/li/cil/oc/util/BlockPosition.scala b/src/main/scala/li/cil/oc/util/BlockPosition.scala index e7b120e8f7..04c9e295a9 100644 --- a/src/main/scala/li/cil/oc/util/BlockPosition.scala +++ b/src/main/scala/li/cil/oc/util/BlockPosition.scala @@ -3,10 +3,10 @@ package li.cil.oc.util import com.google.common.hash.Hashing import li.cil.oc.api.network.EnvironmentHost import net.minecraft.entity.Entity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.AxisAlignedBB import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Vec3d +import net.minecraft.util.math.vector.Vector3d import net.minecraft.world.World class BlockPosition(val x: Int, val y: Int, val z: Int, val world: Option[World]) { @@ -17,22 +17,22 @@ class BlockPosition(val x: Int, val y: Int, val z: Int, val world: Option[World] world ) - def offset(direction: EnumFacing, n: Int) = new BlockPosition( - x + direction.getFrontOffsetX * n, - y + direction.getFrontOffsetY * n, - z + direction.getFrontOffsetZ * n, + def offset(direction: Direction, n: Int) = new BlockPosition( + x + direction.getStepX * n, + y + direction.getStepY * n, + z + direction.getStepZ * n, world ) - def offset(direction: EnumFacing): BlockPosition = offset(direction, 1) + def offset(direction: Direction): BlockPosition = offset(direction, 1) - def offset(x: Double, y: Double, z: Double) = new Vec3d(this.x + x, this.y + y, this.z + z) + def offset(x: Double, y: Double, z: Double) = new Vector3d(this.x + x, this.y + y, this.z + z) def bounds = new AxisAlignedBB(x, y, z, x + 1, y + 1, z + 1) def toBlockPos = new BlockPos(x, y, z) - def toVec3 = new Vec3d(x + 0.5, y + 0.5, z + 0.5) + def toVec3 = new Vector3d(x + 0.5, y + 0.5, z + 0.5) override def equals(obj: scala.Any) = obj match { case position: BlockPosition => position.x == x && position.y == y && position.z == z && position.world == world @@ -61,13 +61,13 @@ object BlockPosition { def apply(x: Double, y: Double, z: Double) = new BlockPosition(x, y, z, None) - def apply(v: Vec3d) = new BlockPosition(v.x, v.y, v.z, None) + def apply(v: Vector3d) = new BlockPosition(v.x, v.y, v.z, None) - def apply(v: Vec3d, world: World) = new BlockPosition(v.x, v.y, v.z, Option(world)) + def apply(v: Vector3d, world: World) = new BlockPosition(v.x, v.y, v.z, Option(world)) def apply(host: EnvironmentHost): BlockPosition = BlockPosition(host.xPosition, host.yPosition, host.zPosition, host.world) - def apply(entity: Entity): BlockPosition = BlockPosition(entity.posX, entity.posY, entity.posZ, entity.world) + def apply(entity: Entity): BlockPosition = BlockPosition(entity.getX, entity.getY, entity.getZ, entity.level) def apply(pos: BlockPos, world: World): BlockPosition = BlockPosition(pos.getX, pos.getY, pos.getZ, world) diff --git a/src/main/scala/li/cil/oc/util/Color.scala b/src/main/scala/li/cil/oc/util/Color.scala index 8d319ccb08..a9d66cc346 100644 --- a/src/main/scala/li/cil/oc/util/Color.scala +++ b/src/main/scala/li/cil/oc/util/Color.scala @@ -1,74 +1,39 @@ package li.cil.oc.util -import net.minecraft.item.EnumDyeColor +import net.minecraft.item.DyeColor import net.minecraft.item.ItemStack -import net.minecraftforge.oredict.OreDictionary -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object Color { val rgbValues = Map( - EnumDyeColor.BLACK -> 0x444444, // 0x1E1B1B - EnumDyeColor.RED -> 0xB3312C, - EnumDyeColor.GREEN -> 0x339911, // 0x3B511A - EnumDyeColor.BROWN -> 0x51301A, - EnumDyeColor.BLUE -> 0x6666FF, // 0x253192 - EnumDyeColor.PURPLE -> 0x7B2FBE, - EnumDyeColor.CYAN -> 0x66FFFF, // 0x287697 - EnumDyeColor.SILVER -> 0xABABAB, - EnumDyeColor.GRAY -> 0x666666, // 0x434343 - EnumDyeColor.PINK -> 0xD88198, - EnumDyeColor.LIME -> 0x66FF66, // 0x41CD34 - EnumDyeColor.YELLOW -> 0xFFFF66, // 0xDECF2A - EnumDyeColor.LIGHT_BLUE -> 0xAAAAFF, // 0x6689D3 - EnumDyeColor.MAGENTA -> 0xC354CD, - EnumDyeColor.ORANGE -> 0xEB8844, - EnumDyeColor.WHITE -> 0xF0F0F0 + DyeColor.BLACK -> 0x444444, // 0x1E1B1B + DyeColor.RED -> 0xB3312C, + DyeColor.GREEN -> 0x339911, // 0x3B511A + DyeColor.BROWN -> 0x51301A, + DyeColor.BLUE -> 0x6666FF, // 0x253192 + DyeColor.PURPLE -> 0x7B2FBE, + DyeColor.CYAN -> 0x66FFFF, // 0x287697 + DyeColor.LIGHT_GRAY -> 0xABABAB, + DyeColor.GRAY -> 0x666666, // 0x434343 + DyeColor.PINK -> 0xD88198, + DyeColor.LIME -> 0x66FF66, // 0x41CD34 + DyeColor.YELLOW -> 0xFFFF66, // 0xDECF2A + DyeColor.LIGHT_BLUE -> 0xAAAAFF, // 0x6689D3 + DyeColor.MAGENTA -> 0xC354CD, + DyeColor.ORANGE -> 0xEB8844, + DyeColor.WHITE -> 0xF0F0F0 ) - val dyes = Array( - "dyeBlack", - "dyeRed", - "dyeGreen", - "dyeBrown", - "dyeBlue", - "dyePurple", - "dyeCyan", - "dyeLightGray", - "dyeGray", - "dyePink", - "dyeLime", - "dyeYellow", - "dyeLightBlue", - "dyeMagenta", - "dyeOrange", - "dyeWhite") + val byName = DyeColor.values.map(col => (col.getName, col)).toMap - val byOreName = Map( - "dyeBlack" -> EnumDyeColor.BLACK, - "dyeRed" -> EnumDyeColor.RED, - "dyeGreen" -> EnumDyeColor.GREEN, - "dyeBrown" -> EnumDyeColor.BROWN, - "dyeBlue" -> EnumDyeColor.BLUE, - "dyePurple" -> EnumDyeColor.PURPLE, - "dyeCyan" -> EnumDyeColor.CYAN, - "dyeLightGray" -> EnumDyeColor.SILVER, - "dyeGray" -> EnumDyeColor.GRAY, - "dyePink" -> EnumDyeColor.PINK, - "dyeLime" -> EnumDyeColor.LIME, - "dyeYellow" -> EnumDyeColor.YELLOW, - "dyeLightBlue" -> EnumDyeColor.LIGHT_BLUE, - "dyeMagenta" -> EnumDyeColor.MAGENTA, - "dyeOrange" -> EnumDyeColor.ORANGE, - "dyeWhite" -> EnumDyeColor.WHITE) + val byTag = DyeColor.values.map(col => (col.getTag.getName, col)).toMap - val byTier = Array(EnumDyeColor.SILVER, EnumDyeColor.YELLOW, EnumDyeColor.CYAN, EnumDyeColor.MAGENTA) + val byTier = Array(DyeColor.LIGHT_GRAY, DyeColor.YELLOW, DyeColor.CYAN, DyeColor.MAGENTA) - def byMeta(meta: EnumDyeColor) = byOreName(dyes(meta.getDyeDamage)) - - def findDye(stack: ItemStack) = byOreName.keys.find(OreDictionary.getOres(_).exists(oreStack => OreDictionary.itemMatches(stack, oreStack, false))) + def findDye(stack: ItemStack) = byTag.keys.find(stack.getItem.getTags.contains) def isDye(stack: ItemStack) = findDye(stack).isDefined - def dyeColor(stack: ItemStack) = findDye(stack).fold(EnumDyeColor.MAGENTA)(byOreName(_)) + def dyeColor(stack: ItemStack) = findDye(stack).fold(DyeColor.MAGENTA)(byTag(_)) } diff --git a/src/main/scala/li/cil/oc/util/DatabaseAccess.scala b/src/main/scala/li/cil/oc/util/DatabaseAccess.scala index 9802eec801..f62ffc7934 100644 --- a/src/main/scala/li/cil/oc/util/DatabaseAccess.scala +++ b/src/main/scala/li/cil/oc/util/DatabaseAccess.scala @@ -4,11 +4,11 @@ import li.cil.oc.api.network.Component import li.cil.oc.api.network.Node import li.cil.oc.server.component.UpgradeDatabase -import scala.collection.JavaConversions +import scala.collection.JavaConverters object DatabaseAccess { def databases(node: Node): Iterable[UpgradeDatabase] = - JavaConversions.iterableAsScalaIterable(node.network.nodes).collect { + JavaConverters.iterableAsScalaIterable(node.network.nodes).collect { case component: Component => component.host match { case db: UpgradeDatabase => db case _ => null diff --git a/src/main/scala/li/cil/oc/util/ExtendedAABB.scala b/src/main/scala/li/cil/oc/util/ExtendedAABB.scala index 8dda6a5a01..0c831ffe26 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedAABB.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedAABB.scala @@ -1,9 +1,9 @@ package li.cil.oc.util -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.AxisAlignedBB import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Vec3d +import net.minecraft.util.math.vector.Vector3d import scala.language.implicitConversions @@ -23,9 +23,9 @@ object ExtendedAABB { bounds.maxZ + pos.getZ) } - def min = new Vec3d(bounds.minX, bounds.minY, bounds.minZ) + def minVec = new Vector3d(bounds.minX, bounds.minY, bounds.minZ) - def max = new Vec3d(bounds.maxX, bounds.maxY, bounds.maxZ) + def maxVec = new Vector3d(bounds.maxX, bounds.maxY, bounds.maxZ) def volume: Int = { val sx = ((bounds.maxX - bounds.minX) * 16).round.toInt @@ -41,18 +41,18 @@ object ExtendedAABB { sx * sy * 2 + sx * sz * 2 + sy * sz * 2 } - def rotateTowards(facing: EnumFacing) = rotateY(facing match { - case EnumFacing.WEST => 3 - case EnumFacing.NORTH => 2 - case EnumFacing.EAST => 1 + def rotateTowards(facing: Direction) = rotateY(facing match { + case Direction.WEST => 3 + case Direction.NORTH => 2 + case Direction.EAST => 1 case _ => 0 }) def rotateY(count: Int): AxisAlignedBB = { - var min = new Vec3d(bounds.minX - 0.5, bounds.minY - 0.5, bounds.minZ - 0.5) - var max = new Vec3d(bounds.maxX - 0.5, bounds.maxY - 0.5, bounds.maxZ - 0.5) - min = min.rotateYaw(count * Math.PI.toFloat * 0.5f) - max = max.rotateYaw(count * Math.PI.toFloat * 0.5f) + var min = new Vector3d(bounds.minX - 0.5, bounds.minY - 0.5, bounds.minZ - 0.5) + var max = new Vector3d(bounds.maxX - 0.5, bounds.maxY - 0.5, bounds.maxZ - 0.5) + min = min.yRot(count * Math.PI.toFloat * 0.5f) + max = max.yRot(count * Math.PI.toFloat * 0.5f) new AxisAlignedBB( (math.min(min.x + 0.5, max.x + 0.5) * 32).round / 32f, (math.min(min.y + 0.5, max.y + 0.5) * 32).round / 32f, diff --git a/src/main/scala/li/cil/oc/util/ExtendedArguments.scala b/src/main/scala/li/cil/oc/util/ExtendedArguments.scala index df744224ac..8fbee2b42f 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedArguments.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedArguments.scala @@ -3,10 +3,10 @@ package li.cil.oc.util import li.cil.oc.api.internal.MultiTank import li.cil.oc.api.machine.Arguments import net.minecraft.inventory.IInventory -import net.minecraft.util.EnumFacing -import net.minecraftforge.fluids.Fluid +import net.minecraft.util.Direction +import net.minecraftforge.fluids.FluidAttributes +import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.capability.IFluidHandler -import net.minecraftforge.fluids.capability.IFluidTankProperties import net.minecraftforge.items.IItemHandler import scala.language.implicitConversions @@ -20,7 +20,7 @@ object ExtendedArguments { if (!isDefined(index) || !hasValue(index)) default else math.max(0, math.min(64, args.checkInteger(index))) - def optFluidCount(index: Int, default: Int = Fluid.BUCKET_VOLUME) = + def optFluidCount(index: Int, default: Int = FluidAttributes.BUCKET_VOLUME) = if (!isDefined(index) || !hasValue(index)) default else math.max(0, args.checkInteger(index)) @@ -51,53 +51,53 @@ object ExtendedArguments { def checkTankProperties(handler: IFluidHandler, n: Int) = { val tank = args.checkInteger(n) - 1 - if (tank < 0 || tank >= handler.getTankProperties.length) { + if (tank < 0 || tank >= handler.getTanks) { throw new IllegalArgumentException("invalid tank index") } - handler.getTankProperties()(tank) + new TankProperties(handler.getTankCapacity(tank), handler.getFluidInTank(tank)) } - def optTankProperties(handler: IFluidHandler, n: Int, default: IFluidTankProperties) = { + def optTankProperties(handler: IFluidHandler, n: Int, default: TankProperties) = { if (!isDefined(n)) default else checkTankProperties(handler, n) } - def checkSideAny(index: Int) = checkSide(index, EnumFacing.values: _*) + def checkSideAny(index: Int) = checkSide(index, Direction.values: _*) - def optSideAny(index: Int, default: EnumFacing) = + def optSideAny(index: Int, default: Direction) = if (!isDefined(index)) default else checkSideAny(index) - def checkSideExcept(index: Int, invalid: EnumFacing*) = checkSide(index, EnumFacing.values.filterNot(invalid.contains): _*) + def checkSideExcept(index: Int, invalid: Direction*) = checkSide(index, Direction.values.filterNot(invalid.contains): _*) - def optSideExcept(index: Int, default: EnumFacing, invalid: EnumFacing*) = + def optSideExcept(index: Int, default: Direction, invalid: Direction*) = if (!isDefined(index)) default else checkSideExcept(index, invalid: _*) - def checkSideForAction(index: Int) = checkSide(index, EnumFacing.SOUTH, EnumFacing.UP, EnumFacing.DOWN) + def checkSideForAction(index: Int) = checkSide(index, Direction.SOUTH, Direction.UP, Direction.DOWN) - def optSideForAction(index: Int, default: EnumFacing) = + def optSideForAction(index: Int, default: Direction) = if (!isDefined(index)) default else checkSideForAction(index) - def checkSideForMovement(index: Int) = checkSide(index, EnumFacing.SOUTH, EnumFacing.NORTH, EnumFacing.UP, EnumFacing.DOWN) + def checkSideForMovement(index: Int) = checkSide(index, Direction.SOUTH, Direction.NORTH, Direction.UP, Direction.DOWN) - def optSideForMovement(index: Int, default: EnumFacing) = + def optSideForMovement(index: Int, default: Direction) = if (!isDefined(index)) default else checkSideForMovement(index) - def checkSideForFace(index: Int, facing: EnumFacing) = checkSideExcept(index, facing.getOpposite) + def checkSideForFace(index: Int, facing: Direction) = checkSideExcept(index, facing.getOpposite) - def optSideForFace(index: Int, default: EnumFacing) = + def optSideForFace(index: Int, default: Direction) = if (!isDefined(index)) default else checkSideForAction(index) - private def checkSide(index: Int, allowed: EnumFacing*) = { + private def checkSide(index: Int, allowed: Direction*) = { val side = args.checkInteger(index) if (side < 0 || side > 5) { throw new IllegalArgumentException("invalid side") } - val direction = EnumFacing.getFront(side) + val direction = Direction.from3DDataValue(side) if (allowed.isEmpty || (allowed contains direction)) direction else throw new IllegalArgumentException("unsupported side") } @@ -107,4 +107,7 @@ object ExtendedArguments { private def hasValue(index: Int) = args.checkAny(index) != null } + @Deprecated + class TankProperties(val capacity: Int, val contents: FluidStack) + } diff --git a/src/main/scala/li/cil/oc/util/ExtendedBlock.scala b/src/main/scala/li/cil/oc/util/ExtendedBlock.scala index 6842bfa122..2358d51b21 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedBlock.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedBlock.scala @@ -1,8 +1,9 @@ package li.cil.oc.util import net.minecraft.block.Block -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraftforge.fluids.IFluidBlock +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction import scala.language.implicitConversions @@ -11,23 +12,23 @@ object ExtendedBlock { implicit def extendedBlock(block: Block): ExtendedBlock = new ExtendedBlock(block) class ExtendedBlock(val block: Block) { + @Deprecated def isAir(position: BlockPosition) = block.isAir(position.world.get.getBlockState(position.toBlockPos), position.world.get, position.toBlockPos) - def isReplaceable(position: BlockPosition) = block.isReplaceable(position.world.get, position.toBlockPos) + @Deprecated + def isReplaceable(position: BlockPosition) = block.defaultBlockState.getMaterial.isReplaceable - def getBlockHardness(position: BlockPosition) = block.getBlockHardness(position.world.get.getBlockState(position.toBlockPos), position.world.get, position.toBlockPos) + @Deprecated + def getBlockHardness(position: BlockPosition) = position.world.get.getBlockState(position.toBlockPos).getDestroySpeed(position.world.get, position.toBlockPos) - def getSelectedBoundingBoxFromPool(position: BlockPosition) = block.getSelectedBoundingBox(position.world.get.getBlockState(position.toBlockPos), position.world.get, position.toBlockPos) - - def getCollisionBoundingBoxFromPool(position: BlockPosition) = block.getCollisionBoundingBox(position.world.get.getBlockState(position.toBlockPos), position.world.get, position.toBlockPos) - - def getComparatorInputOverride(position: BlockPosition, side: EnumFacing) = block.getComparatorInputOverride(position.world.get.getBlockState(position.toBlockPos), position.world.get, position.toBlockPos) + @Deprecated + def getComparatorInputOverride(position: BlockPosition, side: Direction) = block.getAnalogOutputSignal(position.world.get.getBlockState(position.toBlockPos), position.world.get, position.toBlockPos) } implicit def extendedFluidBlock(block: IFluidBlock): ExtendedFluidBlock = new ExtendedFluidBlock(block) class ExtendedFluidBlock(val block: IFluidBlock) { - def drain(position: BlockPosition, doDrain: Boolean) = block.drain(position.world.get, position.toBlockPos, doDrain) + def drain(position: BlockPosition, action: FluidAction) = block.drain(position.world.get, position.toBlockPos, action) def canDrain(position: BlockPosition) = block.canDrain(position.world.get, position.toBlockPos) diff --git a/src/main/scala/li/cil/oc/util/ExtendedEnumFacing.scala b/src/main/scala/li/cil/oc/util/ExtendedEnumFacing.scala index 3c8b89f259..6e5ffea946 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedEnumFacing.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedEnumFacing.scala @@ -1,14 +1,14 @@ package li.cil.oc.util -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import scala.language.implicitConversions object ExtendedEnumFacing { - implicit def extendedEnumFacing(facing: EnumFacing): ExtendedEnumFacing = new ExtendedEnumFacing(facing) + implicit def ExtendedEnumFacing(facing: Direction): ExtendedEnumFacing = new ExtendedEnumFacing(facing) - class ExtendedEnumFacing(val facing: EnumFacing) { - // Copy-pasta from old Forge's ForgeDirection, because MC's equivalent in EnumFacing is client side only \o/ + class ExtendedEnumFacing(val facing: Direction) { + // Copy-pasta from old Forge's ForgeDirection, because MC's equivalent in Direction is client side only \o/ private val ROTATION_MATRIX = Array( Array(0, 1, 4, 5, 3, 2, 6), Array(0, 1, 5, 4, 2, 3, 6), @@ -18,8 +18,8 @@ object ExtendedEnumFacing { Array(3, 2, 0, 1, 4, 5, 6), Array(0, 1, 2, 3, 4, 5, 6)) - def getRotation(axis: EnumFacing) = { - EnumFacing.getFront(ROTATION_MATRIX(axis.ordinal)(facing.ordinal)) + def getRotation(axis: Direction) = { + Direction.from3DDataValue(ROTATION_MATRIX(axis.ordinal)(facing.ordinal)) } } diff --git a/src/main/scala/li/cil/oc/util/ExtendedInventory.scala b/src/main/scala/li/cil/oc/util/ExtendedInventory.scala index 9cc44db3db..d404f0f2c7 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedInventory.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedInventory.scala @@ -11,11 +11,11 @@ object ExtendedInventory { implicit def extendedInventory(inventory: IInventory): ExtendedInventory = new ExtendedInventory(inventory) class ExtendedInventory(val inventory: IInventory) extends mutable.IndexedSeq[ItemStack] { - override def length = inventory.getSizeInventory + override def length = inventory.getContainerSize - override def update(idx: Int, elem: ItemStack) = inventory.setInventorySlotContents(idx, elem) + override def update(idx: Int, elem: ItemStack) = inventory.setItem(idx, elem) - override def apply(idx: Int) = inventory.getStackInSlot(idx) + override def apply(idx: Int) = inventory.getItem(idx) } } diff --git a/src/main/scala/li/cil/oc/util/ExtendedLuaState.scala b/src/main/scala/li/cil/oc/util/ExtendedLuaState.scala index a7fa03ee9b..0f739e9d25 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedLuaState.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedLuaState.scala @@ -9,7 +9,7 @@ import li.cil.repack.com.naef.jnlua.JavaFunction import li.cil.repack.com.naef.jnlua.LuaState import li.cil.repack.com.naef.jnlua.LuaType -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable import scala.language.implicitConversions import scala.math.ScalaNumber @@ -37,7 +37,7 @@ object ExtendedLuaState { case null => null case primitive => primitive.asInstanceOf[AnyRef] }) match { - case null | Unit | _: BoxedUnit => lua.pushNil() + case null | () | _: BoxedUnit => lua.pushNil() case value: java.lang.Boolean => lua.pushBoolean(value.booleanValue) case value: java.lang.Byte => lua.pushNumber(value.byteValue) case value: java.lang.Character => lua.pushString(String.valueOf(value)) @@ -68,7 +68,7 @@ object ExtendedLuaState { } } - def pushList(obj: AnyRef, list: Iterator[(Any, Int)], memo: util.IdentityHashMap[Any, Int]) { + def pushList(obj: Any, list: Iterator[(Any, Int)], memo: util.IdentityHashMap[Any, Int]) { lua.newTable() val tableIndex = lua.getTop memo += obj -> tableIndex @@ -86,7 +86,7 @@ object ExtendedLuaState { lua.rawSet(-3) } - def pushTable(obj: AnyRef, map: Map[_, _], memo: util.IdentityHashMap[Any, Int]) { + def pushTable(obj: Any, map: Map[_, _], memo: util.IdentityHashMap[Any, Int]) { lua.newTable(0, map.size) val tableIndex = lua.getTop memo += obj -> tableIndex diff --git a/src/main/scala/li/cil/oc/util/ExtendedNBT.scala b/src/main/scala/li/cil/oc/util/ExtendedNBT.scala index 3f604b48cc..9244d1888c 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedNBT.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedNBT.scala @@ -3,10 +3,11 @@ package li.cil.oc.util import com.google.common.base.Charsets import net.minecraft.item.ItemStack import net.minecraft.nbt._ -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraftforge.common.util.Constants.NBT -import scala.collection.convert.WrapAsScala._ +import scala.collection.JavaConverters.mapAsScalaMap +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable import scala.language.implicitConversions import scala.language.reflectiveCalls @@ -14,62 +15,62 @@ import scala.reflect.ClassTag object ExtendedNBT { - implicit def toNbt(value: Boolean): NBTTagByte = new NBTTagByte(if (value) 1 else 0) + implicit def toNbt(value: Boolean): ByteNBT = ByteNBT.valueOf(value) - implicit def toNbt(value: Byte): NBTTagByte = new NBTTagByte(value) + implicit def toNbt(value: Byte): ByteNBT = ByteNBT.valueOf(value) - implicit def toNbt(value: Short): NBTTagShort = new NBTTagShort(value) + implicit def toNbt(value: Short): ShortNBT = ShortNBT.valueOf(value) - implicit def toNbt(value: Int): NBTTagInt = new NBTTagInt(value) + implicit def toNbt(value: Int): IntNBT = IntNBT.valueOf(value) - implicit def toNbt(value: Long): NBTTagLong = new NBTTagLong(value) + implicit def toNbt(value: Long): LongNBT = LongNBT.valueOf(value) - implicit def toNbt(value: Float): NBTTagFloat = new NBTTagFloat(value) + implicit def toNbt(value: Float): FloatNBT = FloatNBT.valueOf(value) - implicit def toNbt(value: Double): NBTTagDouble = new NBTTagDouble(value) + implicit def toNbt(value: Double): DoubleNBT = DoubleNBT.valueOf(value) - implicit def toNbt(value: Array[Byte]): NBTTagByteArray = new NBTTagByteArray(value) + implicit def toNbt(value: Array[Byte]): ByteArrayNBT = new ByteArrayNBT(value) - implicit def toNbt(value: Array[Int]): NBTTagIntArray = new NBTTagIntArray(value) + implicit def toNbt(value: Array[Int]): IntArrayNBT = new IntArrayNBT(value) - implicit def toNbt(value: Array[Boolean]): NBTTagByteArray = new NBTTagByteArray(value.map(if (_) 1: Byte else 0: Byte)) + implicit def toNbt(value: Array[Boolean]): ByteArrayNBT = new ByteArrayNBT(value.map(if (_) 1: Byte else 0: Byte)) - implicit def toNbt(value: String): NBTTagString = new NBTTagString(value) + implicit def toNbt(value: String): StringNBT = StringNBT.valueOf(value) - implicit def toNbt(value: ItemStack): NBTTagCompound = { - val nbt = new NBTTagCompound() + implicit def toNbt(value: ItemStack): CompoundNBT = { + val nbt = new CompoundNBT() if (value != null) { - value.writeToNBT(nbt) + value.save(nbt) } nbt } - implicit def toNbt(value: NBTTagCompound => Unit): NBTTagCompound = { - val nbt = new NBTTagCompound() + implicit def toNbt(value: CompoundNBT => Unit): CompoundNBT = { + val nbt = new CompoundNBT() value(nbt) nbt } - implicit def toNbt(value: Map[String, _]): NBTTagCompound = { - val nbt = new NBTTagCompound() + implicit def toNbt(value: Map[String, _]): CompoundNBT = { + val nbt = new CompoundNBT() for ((key, value) <- value) value match { - case value: Boolean => nbt.setTag(key, value) - case value: Byte => nbt.setTag(key, value) - case value: Short => nbt.setTag(key, value) - case value: Int => nbt.setTag(key, value) - case value: Long => nbt.setTag(key, value) - case value: Float => nbt.setTag(key, value) - case value: Double => nbt.setTag(key, value) - case value: Array[Byte] => nbt.setTag(key, value) - case value: Array[Int] => nbt.setTag(key, value) - case value: String => nbt.setTag(key, value) - case value: ItemStack => nbt.setTag(key, value) + case value: Boolean => nbt.put(key, value) + case value: Byte => nbt.put(key, value) + case value: Short => nbt.put(key, value) + case value: Int => nbt.put(key, value) + case value: Long => nbt.put(key, value) + case value: Float => nbt.put(key, value) + case value: Double => nbt.put(key, value) + case value: Array[Byte] => nbt.put(key, value) + case value: Array[Int] => nbt.put(key, value) + case value: String => nbt.put(key, value) + case value: ItemStack => nbt.put(key, value) case _ => } nbt } - def typedMapToNbt(map: Map[_, _]): NBTBase = { + def typedMapToNbt(map: Map[_, _]): INBT = { def mapToList(value: Array[(_, _)]) = value.collect { // Ignore, can be stuff like the 'n' introduced by Lua's `pack`. case (k: Number, v) => k -> v @@ -93,64 +94,64 @@ object ExtendedNBT { val nbtValue = typeAndValue.get("value") nbtType match { case Some(n: Number) => n.intValue() match { - case NBT.TAG_BYTE => new NBTTagByte(nbtValue match { + case NBT.TAG_BYTE => ByteNBT.valueOf(nbtValue match { case Some(v: Number) => v.byteValue() case _ => throw new IllegalArgumentException("Illegal or missing value.") }) - case NBT.TAG_SHORT => new NBTTagShort(nbtValue match { + case NBT.TAG_SHORT => ShortNBT.valueOf(nbtValue match { case Some(v: Number) => v.shortValue() case _ => throw new IllegalArgumentException("Illegal or missing value.") }) - case NBT.TAG_INT => new NBTTagInt(nbtValue match { + case NBT.TAG_INT => IntNBT.valueOf(nbtValue match { case Some(v: Number) => v.intValue() case _ => throw new IllegalArgumentException("Illegal or missing value.") }) - case NBT.TAG_LONG => new NBTTagLong(nbtValue match { + case NBT.TAG_LONG => LongNBT.valueOf(nbtValue match { case Some(v: Number) => v.longValue() case _ => throw new IllegalArgumentException("Illegal or missing value.") }) - case NBT.TAG_FLOAT => new NBTTagFloat(nbtValue match { + case NBT.TAG_FLOAT => FloatNBT.valueOf(nbtValue match { case Some(v: Number) => v.floatValue() case _ => throw new IllegalArgumentException("Illegal or missing value.") }) - case NBT.TAG_DOUBLE => new NBTTagDouble(nbtValue match { + case NBT.TAG_DOUBLE => DoubleNBT.valueOf(nbtValue match { case Some(v: Number) => v.doubleValue() case _ => throw new IllegalArgumentException("Illegal or missing value.") }) - case NBT.TAG_BYTE_ARRAY => new NBTTagByteArray(asList(nbtValue).map { + case NBT.TAG_BYTE_ARRAY => new ByteArrayNBT(asList(nbtValue).map { case n: Number => n.byteValue() case _ => throw new IllegalArgumentException("Illegal value.") }.toArray) - case NBT.TAG_STRING => new NBTTagString(nbtValue match { + case NBT.TAG_STRING => StringNBT.valueOf(nbtValue match { case Some(v: String) => v case Some(v: Array[Byte]) => new String(v, Charsets.UTF_8) case _ => throw new IllegalArgumentException("Illegal or missing value.") }) case NBT.TAG_LIST => - val list = new NBTTagList() - asList(nbtValue).map(v => asMap(Option(v))).foreach(v => list.appendTag(typedMapToNbt(v))) + val list = new ListNBT() + asList(nbtValue).map(v => asMap(Option(v))).foreach(v => list.add(typedMapToNbt(v))) list case NBT.TAG_COMPOUND => - val nbt = new NBTTagCompound() + val nbt = new CompoundNBT() val values = asMap[String](nbtValue) for ((name, entry) <- values) { - try nbt.setTag(name, typedMapToNbt(asMap[Any](Option(entry)))) catch { + try nbt.put(name, typedMapToNbt(asMap[Any](Option(entry)))) catch { case t: Throwable => throw new IllegalArgumentException(s"Error converting entry '$name': ${t.getMessage}") } } nbt case NBT.TAG_INT_ARRAY => - new NBTTagIntArray(asList(nbtValue).map { + new IntArrayNBT(asList(nbtValue).map { case n: Number => n.intValue() case _ => throw new IllegalArgumentException() }.toArray) @@ -162,123 +163,123 @@ object ExtendedNBT { } } - implicit def booleanIterableToNbt(value: Iterable[Boolean]): Iterable[NBTTagByte] = value.map(toNbt) + implicit def booleanIterableToNbt(value: Iterable[Boolean]): Iterable[ByteNBT] = value.map(toNbt) - implicit def byteIterableToNbt(value: Iterable[Byte]): Iterable[NBTTagByte] = value.map(toNbt) + implicit def byteIterableToNbt(value: Iterable[Byte]): Iterable[ByteNBT] = value.map(toNbt) - implicit def shortIterableToNbt(value: Iterable[Short]): Iterable[NBTTagShort] = value.map(toNbt) + implicit def shortIterableToNbt(value: Iterable[Short]): Iterable[ShortNBT] = value.map(toNbt) - implicit def intIterableToNbt(value: Iterable[Int]): Iterable[NBTTagInt] = value.map(toNbt) + implicit def intIterableToNbt(value: Iterable[Int]): Iterable[IntNBT] = value.map(toNbt) - implicit def intArrayIterableToNbt(value: Iterable[Array[Int]]): Iterable[NBTTagIntArray] = value.map(toNbt) + implicit def intArrayIterableToNbt(value: Iterable[Array[Int]]): Iterable[IntArrayNBT] = value.map(toNbt) - implicit def longIterableToNbt(value: Iterable[Long]): Iterable[NBTTagLong] = value.map(toNbt) + implicit def longIterableToNbt(value: Iterable[Long]): Iterable[LongNBT] = value.map(toNbt) - implicit def floatIterableToNbt(value: Iterable[Float]): Iterable[NBTTagFloat] = value.map(toNbt) + implicit def floatIterableToNbt(value: Iterable[Float]): Iterable[FloatNBT] = value.map(toNbt) - implicit def doubleIterableToNbt(value: Iterable[Double]): Iterable[NBTTagDouble] = value.map(toNbt) + implicit def doubleIterableToNbt(value: Iterable[Double]): Iterable[DoubleNBT] = value.map(toNbt) - implicit def byteArrayIterableToNbt(value: Iterable[Array[Byte]]): Iterable[NBTTagByteArray] = value.map(toNbt) + implicit def byteArrayIterableToNbt(value: Iterable[Array[Byte]]): Iterable[ByteArrayNBT] = value.map(toNbt) - implicit def stringIterableToNbt(value: Iterable[String]): Iterable[NBTTagString] = value.map(toNbt) + implicit def stringIterableToNbt(value: Iterable[String]): Iterable[StringNBT] = value.map(toNbt) - implicit def writableIterableToNbt(value: Iterable[NBTTagCompound => Unit]): Iterable[NBTTagCompound] = value.map(toNbt) + implicit def writableIterableToNbt(value: Iterable[CompoundNBT => Unit]): Iterable[CompoundNBT] = value.map(toNbt) - implicit def itemStackIterableToNbt(value: Iterable[ItemStack]): Iterable[NBTTagCompound] = value.map(toNbt) + implicit def itemStackIterableToNbt(value: Iterable[ItemStack]): Iterable[CompoundNBT] = value.map(toNbt) - implicit def extendNBTBase(nbt: NBTBase): ExtendedNBTBase = new ExtendedNBTBase(nbt) + implicit def extendINBT(nbt: INBT): ExtendedINBT = new ExtendedINBT(nbt) - implicit def extendNBTTagCompound(nbt: NBTTagCompound): ExtendedNBTTagCompound = new ExtendedNBTTagCompound(nbt) + implicit def extendCompoundNBT(nbt: CompoundNBT): ExtendedCompoundNBT = new ExtendedCompoundNBT(nbt) - implicit def extendNBTTagList(nbt: NBTTagList): ExtendedNBTTagList = new ExtendedNBTTagList(nbt) + implicit def extendListNBT(nbt: ListNBT): ExtendedListNBT = new ExtendedListNBT(nbt) - class ExtendedNBTBase(val nbt: NBTBase) { + class ExtendedINBT(val nbt: INBT) { def toTypedMap: Map[String, _] = Map("type" -> nbt.getId, "value" -> (nbt match { - case tag: NBTTagByte => tag.getByte - case tag: NBTTagShort => tag.getShort - case tag: NBTTagInt => tag.getInt - case tag: NBTTagLong => tag.getLong - case tag: NBTTagFloat => tag.getFloat - case tag: NBTTagDouble => tag.getDouble - case tag: NBTTagByteArray => tag.getByteArray - case tag: NBTTagString => tag.getString - case tag: NBTTagList => tag.map((entry: NBTBase) => entry.toTypedMap) - case tag: NBTTagCompound => tag.getKeySet.collect { - case key: String => key -> tag.getTag(key).toTypedMap + case tag: ByteNBT => tag.getAsByte + case tag: ShortNBT => tag.getAsShort + case tag: IntNBT => tag.getAsInt + case tag: LongNBT => tag.getAsLong + case tag: FloatNBT => tag.getAsFloat + case tag: DoubleNBT => tag.getAsDouble + case tag: ByteArrayNBT => tag.getAsByteArray + case tag: StringNBT => tag.getAsString + case tag: ListNBT => tag.map((entry: INBT) => entry.toTypedMap) + case tag: CompoundNBT => tag.getAllKeys.collect { + case key: String => key -> tag.get(key).toTypedMap }.toMap - case tag: NBTTagIntArray => tag.getIntArray + case tag: IntArrayNBT => tag.getAsIntArray case _ => throw new IllegalArgumentException() })) } - class ExtendedNBTTagCompound(val nbt: NBTTagCompound) { - def setNewCompoundTag(name: String, f: (NBTTagCompound) => Any) = { - val t = new NBTTagCompound() + class ExtendedCompoundNBT(val nbt: CompoundNBT) { + def setNewCompoundTag(name: String, f: (CompoundNBT) => Any) = { + val t = new CompoundNBT() f(t) - nbt.setTag(name, t) + nbt.put(name, t) nbt } - def setNewTagList(name: String, values: Iterable[NBTBase]) = { - val t = new NBTTagList() + def setNewTagList(name: String, values: Iterable[INBT]) = { + val t = new ListNBT() t.append(values) - nbt.setTag(name, t) + nbt.put(name, t) nbt } - def setNewTagList(name: String, values: NBTBase*): NBTTagCompound = setNewTagList(name, values) + def setNewTagList(name: String, values: INBT*): CompoundNBT = setNewTagList(name, values) def getDirection(name: String) = { nbt.getByte(name) match { - case id if id < 0 || id > EnumFacing.values.length => None - case id => Option(EnumFacing.getFront(id)) + case id if id < 0 || id > Direction.values.length => None + case id => Option(Direction.from3DDataValue(id)) } } - def setDirection(name: String, d: Option[EnumFacing]): Unit = { + def setDirection(name: String, d: Option[Direction]): Unit = { d match { - case Some(side) => nbt.setByte(name, side.ordinal.toByte) - case _ => nbt.setByte(name, -1: Byte) + case Some(side) => nbt.putByte(name, side.ordinal.toByte) + case _ => nbt.putByte(name, -1: Byte) } } def getBooleanArray(name: String) = nbt.getByteArray(name).map(_ == 1) - def setBooleanArray(name: String, value: Array[Boolean]) = nbt.setTag(name, toNbt(value)) + def setBooleanArray(name: String, value: Array[Boolean]) = nbt.put(name, toNbt(value)) } - class ExtendedNBTTagList(val nbt: NBTTagList) { - def appendNewCompoundTag(f: (NBTTagCompound) => Unit) { - val t = new NBTTagCompound() + class ExtendedListNBT(val nbt: ListNBT) { + def appendNewCompoundTag(f: (CompoundNBT) => Unit) { + val t = new CompoundNBT() f(t) - nbt.appendTag(t) + nbt.add(t) } - def append(values: Iterable[NBTBase]) { + def append(values: Iterable[INBT]) { for (value <- values) { - nbt.appendTag(value) + nbt.add(value) } } - def append(values: NBTBase*): Unit = append(values) + def append(values: INBT*): Unit = append(values) - def foreach[Tag <: NBTBase](f: Tag => Unit) { - val iterable = nbt.copy(): NBTTagList - while (iterable.tagCount > 0) { - f(iterable.removeTag(0).asInstanceOf[Tag]) + def foreach[Tag <: INBT](f: Tag => Unit) { + val iterable = nbt.copy(): ListNBT + while (iterable.size > 0) { + f((iterable.remove(0): INBT).asInstanceOf[Tag]) } } - def map[Tag <: NBTBase, Value](f: Tag => Value): IndexedSeq[Value] = { - val iterable = nbt.copy(): NBTTagList + def map[Tag <: INBT, Value](f: Tag => Value): IndexedSeq[Value] = { + val iterable = nbt.copy(): ListNBT val buffer = mutable.ArrayBuffer.empty[Value] - while (iterable.tagCount > 0) { - buffer += f(iterable.removeTag(0).asInstanceOf[Tag]) + while (iterable.size > 0) { + buffer += f((iterable.remove(0): INBT).asInstanceOf[Tag]) } - buffer + buffer.toIndexedSeq } - def toArray[Tag: ClassTag] = map((t: Tag) => t).toArray + def toTagArray[Tag: ClassTag] = map((t: Tag) => t).toArray } } diff --git a/src/main/scala/li/cil/oc/util/ExtendedWorld.scala b/src/main/scala/li/cil/oc/util/ExtendedWorld.scala index 01ce67ebe1..688537c95c 100644 --- a/src/main/scala/li/cil/oc/util/ExtendedWorld.scala +++ b/src/main/scala/li/cil/oc/util/ExtendedWorld.scala @@ -2,82 +2,97 @@ package li.cil.oc.util import li.cil.oc.api.network.EnvironmentHost import net.minecraft.block.Block -import net.minecraft.block.state.IBlockState -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.block.Blocks +import net.minecraft.block.BlockState +import net.minecraft.block.material.Material +import net.minecraft.entity.player.PlayerEntity import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import net.minecraft.util.math.BlockPos -import net.minecraft.world.IBlockAccess +import net.minecraft.world.IBlockReader import net.minecraft.world.World import scala.language.implicitConversions object ExtendedWorld { - implicit def extendedBlockAccess(world: IBlockAccess): ExtendedBlockAccess = new ExtendedBlockAccess(world) + implicit def extendedBlockAccess(world: IBlockReader): ExtendedBlockAccess = new ExtendedBlockAccess(world) implicit def extendedWorld(world: World): ExtendedWorld = new ExtendedWorld(world) - class ExtendedBlockAccess(val world: IBlockAccess) { + class ExtendedBlockAccess(val world: IBlockReader) { def getBlock(position: BlockPosition) = world.getBlockState(position.toBlockPos).getBlock def getBlockMapColor(position: BlockPosition) = getBlockMetadata(position).getMapColor(world, position.toBlockPos) def getBlockMetadata(position: BlockPosition) = world.getBlockState(position.toBlockPos) - def getTileEntity(position: BlockPosition): TileEntity = world.getTileEntity(position.toBlockPos) + def getBlockEntity(position: BlockPosition): TileEntity = world.getBlockEntity(position.toBlockPos) - def getTileEntity(host: EnvironmentHost): TileEntity = getTileEntity(BlockPosition(host)) + def getBlockEntity(host: EnvironmentHost): TileEntity = getBlockEntity(BlockPosition(host)) - def isAirBlock(position: BlockPosition) = world.isAirBlock(position.toBlockPos) - - def getLightBrightnessForSkyBlocks(position: BlockPosition, minBrightness: Int) = world.getCombinedLight(position.toBlockPos, minBrightness) + def isAirBlock(position: BlockPosition) = { + val state = world.getBlockState(position.toBlockPos) + state.getBlock.isAir(state, world, position.toBlockPos) + } } class ExtendedWorld(override val world: World) extends ExtendedBlockAccess(world) { - def blockExists(position: BlockPosition) = world.isBlockLoaded(position.toBlockPos) + def blockExists(position: BlockPosition) = world.isLoaded(position.toBlockPos) def breakBlock(position: BlockPosition, drops: Boolean = true) = world.destroyBlock(position.toBlockPos, drops) - def destroyBlockInWorldPartially(entityId: Int, position: BlockPosition, progress: Int) = world.sendBlockBreakProgress(entityId, position.toBlockPos, progress) + def destroyBlockInWorldPartially(entityId: Int, position: BlockPosition, progress: Int) = world.destroyBlockProgress(entityId, position.toBlockPos, progress) - def extinguishFire(player: EntityPlayer, position: BlockPosition, side: EnumFacing) = world.extinguishFire(player, position.toBlockPos, side) + def extinguishFire(player: PlayerEntity, position: BlockPosition, side: Direction) = { + val pos = position.toBlockPos + val state = world.getBlockState(pos) + if (state.getMaterial == Material.FIRE) { + world.setBlock(pos, Blocks.AIR.defaultBlockState, 3) + true + } + else false + } - def getBlockHardness(position: BlockPosition) = getBlock(position).getBlockHardness(world.getBlockState(position.toBlockPos), world, position.toBlockPos) + def getBlockHardness(position: BlockPosition) = world.getBlockState(position.toBlockPos).getDestroySpeed(world, position.toBlockPos) def getBlockHarvestLevel(position: BlockPosition) = getBlock(position).getHarvestLevel(getBlockMetadata(position)) def getBlockHarvestTool(position: BlockPosition) = getBlock(position).getHarvestTool(getBlockMetadata(position)) - def computeRedstoneSignal(position: BlockPosition, side: EnumFacing) = math.max(world.isBlockProvidingPowerTo(position.offset(side), side), world.getIndirectPowerLevelTo(position.offset(side), side)) + def computeRedstoneSignal(position: BlockPosition, side: Direction) = math.max(world.isBlockProvidingPowerTo(position.offset(side), side), world.getIndirectPowerLevelTo(position.offset(side), side)) - def isBlockProvidingPowerTo(position: BlockPosition, side: EnumFacing) = world.getStrongPower(position.toBlockPos, side) + def isBlockProvidingPowerTo(position: BlockPosition, side: Direction) = world.getDirectSignal(position.toBlockPos, side) - def getIndirectPowerLevelTo(position: BlockPosition, side: EnumFacing) = world.getRedstonePower(position.toBlockPos, side) + def getIndirectPowerLevelTo(position: BlockPosition, side: Direction) = world.getSignal(position.toBlockPos, side) - def notifyBlockUpdate(pos: BlockPos): Unit = world.notifyBlockUpdate(pos, world.getBlockState(pos), world.getBlockState(pos), 3) + def notifyBlockUpdate(pos: BlockPos): Unit = world.sendBlockUpdated(pos, world.getBlockState(pos), world.getBlockState(pos), 3) - def notifyBlockUpdate(position: BlockPosition): Unit = notifyBlockUpdate(position, world.getBlockState(position.toBlockPos), world.getBlockState(position.toBlockPos)) + def notifyBlockUpdate(position: BlockPosition): Unit = world.sendBlockUpdated(position.toBlockPos, world.getBlockState(position.toBlockPos), world.getBlockState(position.toBlockPos), 3) - def notifyBlockUpdate(position: BlockPosition, oldState: IBlockState, newState: IBlockState, flags: Int = 3): Unit = world.notifyBlockUpdate(position.toBlockPos, oldState, newState, flags) + def notifyBlockUpdate(position: BlockPosition, oldState: BlockState, newState: BlockState, flags: Int = 3): Unit = world.sendBlockUpdated(position.toBlockPos, oldState, newState, flags) def notifyBlockOfNeighborChange(position: BlockPosition, block: Block) = world.neighborChanged(position.toBlockPos, block, position.toBlockPos) - def notifyBlocksOfNeighborChange(position: BlockPosition, block: Block, updateObservers: Boolean) = world.notifyNeighborsOfStateChange(position.toBlockPos, block, updateObservers) - - def notifyBlocksOfNeighborChange(position: BlockPosition, block: Block, side: EnumFacing) = world.notifyNeighborsOfStateExcept(position.toBlockPos, block, side) + @Deprecated + def notifyBlocksOfNeighborChange(position: BlockPosition, block: Block, updateObservers: Boolean) = world.updateNeighborsAt(position.toBlockPos, block) - def playAuxSFX(id: Int, position: BlockPosition, data: Int) = world.playEvent(id, position.toBlockPos, data) + def notifyBlocksOfNeighborChange(position: BlockPosition, block: Block, side: Direction) = world.updateNeighborsAtExceptFromFacing(position.toBlockPos, block, side) - def setBlock(position: BlockPosition, block: Block) = world.setBlockState(position.toBlockPos, block.getDefaultState) + def playAuxSFX(id: Int, position: BlockPosition, data: Int) = world.levelEvent(id, position.toBlockPos, data) - def setBlock(position: BlockPosition, block: Block, metadata: Int, flag: Int) = world.setBlockState(position.toBlockPos, block.getStateFromMeta(metadata), flag) + def setBlock(position: BlockPosition, block: Block) = world.setBlockAndUpdate(position.toBlockPos, block.defaultBlockState) - def setBlockToAir(position: BlockPosition) = world.setBlockToAir(position.toBlockPos) + @Deprecated + def setBlock(position: BlockPosition, block: Block, metadata: Int, flag: Int) = { + val states = block.getStateDefinition.getPossibleStates + val state = if (metadata >= 0 && metadata < states.size) states.get(metadata) else block.defaultBlockState + world.setBlock(position.toBlockPos, state, flag) + } - def isSideSolid(position: BlockPosition, side: EnumFacing) = world.isSideSolid(position.toBlockPos, side) + def setBlockToAir(position: BlockPosition) = world.setBlockAndUpdate(position.toBlockPos, Blocks.AIR.defaultBlockState) - def isBlockLoaded(position: BlockPosition) = world.isBlockLoaded(position.toBlockPos) + def isLoaded(position: BlockPosition) = world.isLoaded(position.toBlockPos) } } diff --git a/src/main/scala/li/cil/oc/util/FluidUtils.scala b/src/main/scala/li/cil/oc/util/FluidUtils.scala index 2b50bf24e9..1b42e1a498 100644 --- a/src/main/scala/li/cil/oc/util/FluidUtils.scala +++ b/src/main/scala/li/cil/oc/util/FluidUtils.scala @@ -3,23 +3,19 @@ package li.cil.oc.util import li.cil.oc.util.ExtendedBlock._ import li.cil.oc.util.ExtendedWorld._ import net.minecraft.block.Block -import net.minecraft.block.BlockDynamicLiquid -import net.minecraft.block.BlockLiquid -import net.minecraft.block.BlockStaticLiquid -import net.minecraft.init.Blocks +import net.minecraft.block.FlowingFluidBlock +import net.minecraft.block.Blocks +import net.minecraft.fluid.Fluid import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing -import net.minecraftforge.fluids.Fluid -import net.minecraftforge.fluids.FluidRegistry +import net.minecraft.util.Direction +import net.minecraftforge.fluids.FluidAttributes import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.IFluidBlock -import net.minecraftforge.fluids.capability import net.minecraftforge.fluids.capability.CapabilityFluidHandler -import net.minecraftforge.fluids.capability.FluidTankProperties import net.minecraftforge.fluids.capability.IFluidHandler +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction import net.minecraftforge.fluids.capability.IFluidHandlerItem -import net.minecraftforge.fluids.capability.IFluidTankProperties object FluidUtils { /** @@ -27,12 +23,12 @@ object FluidUtils { *

    * This performs special handling for in-world liquids. */ - def fluidHandlerAt(position: BlockPosition, side: EnumFacing): Option[IFluidHandler] = position.world match { - case Some(world) if world.blockExists(position) => world.getTileEntity(position) match { + def fluidHandlerAt(position: BlockPosition, side: Direction): Option[IFluidHandler] = position.world match { + case Some(world) if world.blockExists(position) => world.getBlockEntity(position) match { case handler: IFluidHandler => Option(handler) - case t: TileEntity if t.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side) => - t.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side) match { - case handler: capability.IFluidHandler => Option(handler) + case t: TileEntity if t.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side).isPresent => + t.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, side).orElse(null) match { + case handler: IFluidHandler => Option(handler) case _ => Option(new GenericBlockWrapper(position)) } case _ => Option(new GenericBlockWrapper(position)) @@ -41,8 +37,7 @@ object FluidUtils { } def fluidHandlerOf(stack: ItemStack): IFluidHandlerItem = Option(stack) match { - case Some(itemStack) if itemStack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null) => - itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null) + case Some(itemStack) => itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null).orElse(null) case _ => null } @@ -55,13 +50,13 @@ object FluidUtils { *

    * This returns true if some fluid was transferred. */ - def transferBetweenFluidHandlers(source: IFluidHandler, sink: IFluidHandler, limit: Int = Fluid.BUCKET_VOLUME): Int = { - val drained = source.drain(limit, false) + def transferBetweenFluidHandlers(source: IFluidHandler, sink: IFluidHandler, limit: Int = FluidAttributes.BUCKET_VOLUME): Int = { + val drained = source.drain(limit, FluidAction.SIMULATE) if (drained == null) { return 0 } - val filled = sink.fill(drained, false) - sink.fill(source.drain(filled, true), true) + val filled = sink.fill(drained, FluidAction.SIMULATE) + sink.fill(source.drain(filled, FluidAction.EXECUTE), FluidAction.EXECUTE) } /** @@ -71,39 +66,41 @@ object FluidUtils { * This uses the fluidHandlerAt method, and therefore handles special * cases such as fluid blocks. */ - def transferBetweenFluidHandlersAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sinkPos: BlockPosition, sinkSide: EnumFacing, limit: Int = Fluid.BUCKET_VOLUME): Int = + def transferBetweenFluidHandlersAt(sourcePos: BlockPosition, sourceSide: Direction, sinkPos: BlockPosition, sinkSide: Direction, limit: Int = FluidAttributes.BUCKET_VOLUME): Int = fluidHandlerAt(sourcePos, sourceSide).fold(0)(source => fluidHandlerAt(sinkPos, sinkSide).fold(0)(sink => transferBetweenFluidHandlers(source, sink, limit))) /** * Lookup fluid taking into account flowing liquid blocks... + * For legacy reasons, returns null when the block is not a fluid, not Fluids.EMPTY. */ - def lookupFluidForBlock(block: Block): Fluid = { - if (block == Blocks.FLOWING_LAVA) FluidRegistry.LAVA - else if (block == Blocks.FLOWING_WATER) FluidRegistry.WATER - else FluidRegistry.lookupFluidForBlock(block) + @Deprecated + def lookupFluidForBlock(block: Block): Fluid = block match { + case fluid: FlowingFluidBlock => fluid.getFluid + case _ => null } // ----------------------------------------------------------------------- // private class GenericBlockWrapper(position: BlockPosition) extends IFluidHandler { - def canDrain(fluid: Fluid): Boolean = currentWrapper.fold(false)(_.drain(new FluidStack(fluid, 1), false).amount > 0) + override def getTanks = currentWrapper.fold(0)(_.getTanks) + + override def getFluidInTank(tank: Int) = currentWrapper.fold(FluidStack.EMPTY)(_.getFluidInTank(tank)) - override def drain(resource: FluidStack, doDrain: Boolean): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(resource, doDrain)) + override def getTankCapacity(tank: Int) = currentWrapper.fold(0)(_.getTankCapacity(tank)) - override def drain(maxDrain: Int, doDrain: Boolean): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(maxDrain, doDrain)) + override def isFluidValid(tank: Int, fluid: FluidStack): Boolean = currentWrapper.fold(false)(_.isFluidValid(tank, fluid)) - def canFill(fluid: Fluid): Boolean = currentWrapper.fold(false)(_.fill(new FluidStack(fluid, 1), false) > 0) + override def drain(resource: FluidStack, action: FluidAction): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(resource, action)) - override def fill(resource: FluidStack, doFill: Boolean): Int = currentWrapper.fold(0)(_.fill(resource, doFill)) + override def drain(maxDrain: Int, action: FluidAction): FluidStack = currentWrapper.fold(null: FluidStack)(_.drain(maxDrain, action)) - override def getTankProperties: Array[IFluidTankProperties] = currentWrapper.fold(Array.empty[IFluidTankProperties])(_.getTankProperties) + override def fill(resource: FluidStack, action: FluidAction): Int = currentWrapper.fold(0)(_.fill(resource, action)) def currentWrapper: Option[IFluidHandler] = if (position.world.get.blockExists(position)) position.world.get.getBlock(position) match { case block: IFluidBlock => Option(new FluidBlockWrapper(position, block)) - case block: BlockStaticLiquid if lookupFluidForBlock(block) != null && isFullLiquidBlock => Option(new LiquidBlockWrapper(position, block)) - case block: BlockDynamicLiquid if lookupFluidForBlock(block) != null && isFullLiquidBlock => Option(new LiquidBlockWrapper(position, block)) + case block: FlowingFluidBlock if lookupFluidForBlock(block) != null && isFullLiquidBlock => Option(new LiquidBlockWrapper(position, block)) case block: Block if block.isAir(position) || block.isReplaceable(position) => Option(new AirBlockWrapper(position, block)) case _ => None } @@ -111,84 +108,92 @@ object FluidUtils { def isFullLiquidBlock: Boolean = { val state = position.world.get.getBlockState(position.toBlockPos) - state.getValue(BlockLiquid.LEVEL) == 0 + state.getValue(FlowingFluidBlock.LEVEL) == 0 } } private trait BlockWrapperBase extends IFluidHandler { - protected def uncheckedDrain(doDrain: Boolean): FluidStack + override def getTanks = 1 + + override def getTankCapacity(tank: Int) = FluidAttributes.BUCKET_VOLUME + + protected def uncheckedDrain(action: FluidAction): FluidStack - override def drain(resource: FluidStack, doDrain: Boolean): FluidStack = { - val drained = uncheckedDrain(false) - if (drained != null && (resource == null || (drained.getFluid == resource.getFluid && drained.amount <= resource.amount))) { - uncheckedDrain(doDrain) + override def drain(resource: FluidStack, action: FluidAction): FluidStack = { + val drained = uncheckedDrain(FluidAction.SIMULATE) + if (drained != null && (resource == null || (drained.getFluid == resource.getFluid && drained.getAmount <= resource.getAmount))) { + uncheckedDrain(action) } else null } - override def drain(maxDrain: Int, doDrain: Boolean): FluidStack = { - val drained = uncheckedDrain(false) - if (drained != null && drained.amount <= maxDrain) { - uncheckedDrain(doDrain) + override def drain(maxDrain: Int, action: FluidAction): FluidStack = { + val drained = uncheckedDrain(FluidAction.SIMULATE) + if (drained != null && drained.getAmount <= maxDrain) { + uncheckedDrain(action) } else null } - def canFill(fluid: Fluid): Boolean = false - - override def fill(resource: FluidStack, doFill: Boolean): Int = 0 + override def fill(resource: FluidStack, action: FluidAction): Int = 0 } + @Deprecated private class FluidBlockWrapper(val position: BlockPosition, val block: IFluidBlock) extends BlockWrapperBase { - final val AssumedCapacity = Fluid.BUCKET_VOLUME - - def canDrain(fluid: Fluid): Boolean = block.canDrain(position) + override def getFluidInTank(tank: Int) = block.drain(position, FluidAction.SIMULATE) - override def getTankProperties: Array[IFluidTankProperties] = Array(new FluidTankProperties(new FluidStack(block.getFluid, (block.getFilledPercentage(position) * AssumedCapacity).toInt), AssumedCapacity)) + override def isFluidValid(tank: Int, fluid: FluidStack): Boolean = block.getFluid.isSame(fluid.getFluid) && block.canDrain(position) - override protected def uncheckedDrain(doDrain: Boolean): FluidStack = block.drain(position, doDrain) + override protected def uncheckedDrain(action: FluidAction): FluidStack = block.drain(position, action) } - private class LiquidBlockWrapper(val position: BlockPosition, val block: BlockLiquid) extends BlockWrapperBase { + private class LiquidBlockWrapper(val position: BlockPosition, val block: FlowingFluidBlock) extends BlockWrapperBase { val fluid: Fluid = lookupFluidForBlock(block) - def canDrain(fluid: Fluid): Boolean = true + override def getFluidInTank(tank: Int) = if (isFullLiquidBlock) new FluidStack(fluid, FluidAttributes.BUCKET_VOLUME) else FluidStack.EMPTY - override def getTankProperties: Array[IFluidTankProperties] = Array(new FluidTankProperties(new FluidStack(fluid, Fluid.BUCKET_VOLUME), Fluid.BUCKET_VOLUME)) + override def isFluidValid(tank: Int, fluid: FluidStack): Boolean = block.getFluid.isSame(fluid.getFluid) - override protected def uncheckedDrain(doDrain: Boolean): FluidStack = { - if (doDrain) { + override protected def uncheckedDrain(action: FluidAction): FluidStack = { + if (action.execute) { position.world.get.setBlockToAir(position) } - new FluidStack(fluid, Fluid.BUCKET_VOLUME) + if (isFullLiquidBlock) new FluidStack(fluid, FluidAttributes.BUCKET_VOLUME) else FluidStack.EMPTY + } + + def isFullLiquidBlock: Boolean = { + val state = position.world.get.getBlockState(position.toBlockPos) + state.getValue(FlowingFluidBlock.LEVEL) == 0 } } private class AirBlockWrapper(val position: BlockPosition, val block: Block) extends IFluidHandler { - def canDrain(fluid: Fluid): Boolean = false + override def getTanks = 1 - override def drain(resource: FluidStack, doDrain: Boolean): FluidStack = null + override def getTankCapacity(tank: Int) = FluidAttributes.BUCKET_VOLUME - override def drain(maxDrain: Int, doDrain: Boolean): FluidStack = null + override def getFluidInTank(tank: Int) = FluidStack.EMPTY - def canFill(fluid: Fluid): Boolean = fluid.canBePlacedInWorld + override def drain(resource: FluidStack, action: FluidAction): FluidStack = FluidStack.EMPTY - override def fill(resource: FluidStack, doFill: Boolean): Int = { - if (resource != null && resource.getFluid.canBePlacedInWorld && resource.getFluid.getBlock != null && resource.amount >= 1000) { - if (doFill) { + override def drain(maxDrain: Int, action: FluidAction): FluidStack = FluidStack.EMPTY + + override def isFluidValid(tank: Int, fluid: FluidStack): Boolean = fluid.getFluid.defaultFluidState.createLegacyBlock != null + + override def fill(resource: FluidStack, action: FluidAction): Int = { + if (resource != null && resource.getFluid.defaultFluidState.createLegacyBlock != null && resource.getAmount >= FluidAttributes.BUCKET_VOLUME) { + if (action.execute) { val world = position.world.get if (!world.isAirBlock(position) && !world.containsAnyLiquid(position.bounds)) world.breakBlock(position) - world.setBlock(position, resource.getFluid.getBlock) + world.setBlockAndUpdate(position.toBlockPos, resource.getFluid.defaultFluidState.createLegacyBlock) // This fake neighbor update is required to get stills to start flowing. world.notifyBlockOfNeighborChange(position, world.getBlock(position)) } - Fluid.BUCKET_VOLUME + FluidAttributes.BUCKET_VOLUME } else 0 } - - override def getTankProperties: Array[IFluidTankProperties] = Array.empty } } diff --git a/src/main/scala/li/cil/oc/util/InventoryUtils.scala b/src/main/scala/li/cil/oc/util/InventoryUtils.scala index 6b9595a134..5157528e2e 100644 --- a/src/main/scala/li/cil/oc/util/InventoryUtils.scala +++ b/src/main/scala/li/cil/oc/util/InventoryUtils.scala @@ -1,27 +1,31 @@ package li.cil.oc.util +import java.util.Optional +import java.util.function.Consumer + import li.cil.oc.OpenComputers import li.cil.oc.util.ExtendedWorld._ import li.cil.oc.util.StackOption._ import net.minecraft.entity.Entity -import net.minecraft.entity.item.EntityItem -import net.minecraft.entity.player.EntityPlayer +import net.minecraft.entity.item.ItemEntity +import net.minecraft.entity.player.PlayerEntity import net.minecraft.inventory.IInventory import net.minecraft.inventory.ISidedInventory import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction +import net.minecraft.util.math.vector.Vector3d import net.minecraftforge.items.CapabilityItemHandler import net.minecraftforge.items.IItemHandler import net.minecraftforge.items.IItemHandlerModifiable import net.minecraftforge.items.wrapper.InvWrapper import net.minecraftforge.items.wrapper.SidedInvWrapper -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ object InventoryUtils { - def asItemHandler(inventory: IInventory, side: EnumFacing): IItemHandlerModifiable = inventory match { + def asItemHandler(inventory: IInventory, side: Direction): IItemHandlerModifiable = inventory match { case inv: ISidedInventory if side != null => new SidedInvWrapper(inv, side) case _ => new InvWrapper(inventory) } @@ -36,8 +40,10 @@ object InventoryUtils { def haveSameItemType(stackA: ItemStack, stackB: ItemStack, checkNBT: Boolean = false): Boolean = !stackA.isEmpty && !stackB.isEmpty && stackA.getItem == stackB.getItem && - (!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage) && - (!checkNBT || ItemStack.areItemStackTagsEqual(stackA, stackB)) + (stackA.getDamageValue == stackB.getDamageValue) && + (!checkNBT || ItemStack.tagMatches(stackA, stackB)) + + private def optionToScala[T](opt: Optional[T]): Option[T] = if (opt.isPresent) Some(opt.get) else None /** * Retrieves an actual inventory implementation for a specified world coordinate. @@ -45,20 +51,20 @@ object InventoryUtils { * This performs special handling for (double-)chests and also checks for * mine carts with chests. */ - def inventoryAt(position: BlockPosition, side: EnumFacing): Option[IItemHandler] = position.world match { - case Some(world) if world.blockExists(position) => world.getTileEntity(position) match { - case tile: TileEntity if tile.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side) => Option(tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side)) + def inventoryAt(position: BlockPosition, side: Direction): Option[IItemHandler] = position.world match { + case Some(world) if world.blockExists(position) => world.getBlockEntity(position) match { + case tile: TileEntity if tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side).isPresent => optionToScala(tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side).resolve) case tile: IInventory => Option(asItemHandler(tile, side)) - case _ => world.getEntitiesWithinAABB(classOf[Entity], position.bounds) - .filter(e => !e.isDead && e.hasCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side)) - .map(_.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side)) + case _ => world.getEntitiesOfClass(classOf[Entity], position.bounds) + .filter(e => e.isAlive && e.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side).isPresent) + .map(_.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side).orElse(null)) .find(_ != null) } case _ => None } def anyInventoryAt(position: BlockPosition): Option[IItemHandler] = { - for(side <- null :: EnumFacing.VALUES.toList) { + for(side <- null :: Direction.values.toList) { inventoryAt(position, side) match { case inv: Some[IItemHandler] => return inv case _ => @@ -92,7 +98,7 @@ object InventoryUtils { def insertIntoInventorySlot(stack: ItemStack, inventory: IItemHandler, slot: Int, limit: Int = 64, simulate: Boolean = false): Boolean = (!stack.isEmpty && limit > 0 && stack.getCount > 0) && { val amount = stack.getCount min limit - val toInsert = stack.splitStack(amount) + val toInsert = stack.split(amount) inventory.insertItem(slot, toInsert, simulate) match { case remaining: ItemStack => val result = remaining.getCount < amount @@ -102,7 +108,7 @@ object InventoryUtils { } } - def insertIntoInventorySlot(stack: ItemStack, inventory: IInventory, side: Option[EnumFacing], slot: Int, limit: Int, simulate: Boolean): Boolean = + def insertIntoInventorySlot(stack: ItemStack, inventory: IInventory, side: Option[Direction], slot: Int, limit: Int, simulate: Boolean): Boolean = insertIntoInventorySlot(stack, asItemHandler(inventory, side.orNull), slot, limit, simulate) /** @@ -150,7 +156,7 @@ object InventoryUtils { } } - def extractFromInventorySlot(consumer: (ItemStack) => Unit, inventory: IInventory, side: EnumFacing, slot: Int, limit: Int): Int = + def extractFromInventorySlot(consumer: (ItemStack) => Unit, inventory: IInventory, side: Direction, slot: Int, limit: Int): Int = extractFromInventorySlot(consumer, asItemHandler(inventory, side), slot, limit) /** @@ -186,7 +192,7 @@ object InventoryUtils { success } - def insertIntoInventory(stack: ItemStack, inventory: IInventory, side: Option[EnumFacing], limit: Int, simulate: Boolean, slots: Option[Iterable[Int]]): Boolean = + def insertIntoInventory(stack: ItemStack, inventory: IInventory, side: Option[Direction], limit: Int, simulate: Boolean, slots: Option[Iterable[Int]]): Boolean = insertIntoInventory(stack, asItemHandler(inventory, side.orNull), limit, simulate, slots) /** @@ -209,7 +215,7 @@ object InventoryUtils { 0 } - def extractAnyFromInventory(consumer: ItemStack => Unit, inventory: IInventory, side: EnumFacing, limit: Int): Int = + def extractAnyFromInventory(consumer: ItemStack => Unit, inventory: IInventory, side: Direction, limit: Int): Int = extractAnyFromInventory(consumer, asItemHandler(inventory, side), limit) /** @@ -238,14 +244,14 @@ object InventoryUtils { remaining } - def extractFromInventory(stack: ItemStack, inventory: IInventory, side: EnumFacing, simulate: Boolean, exact: Boolean): ItemStack = + def extractFromInventory(stack: ItemStack, inventory: IInventory, side: Direction, simulate: Boolean, exact: Boolean): ItemStack = extractFromInventory(stack, asItemHandler(inventory, side), simulate, exact) /** * Utility method for calling insertIntoInventory on an inventory * in the world. */ - def insertIntoInventoryAt(stack: ItemStack, position: BlockPosition, side: Option[EnumFacing] = None, limit: Int = 64, simulate: Boolean = false): Boolean = + def insertIntoInventoryAt(stack: ItemStack, position: BlockPosition, side: Option[Direction] = None, limit: Int = 64, simulate: Boolean = false): Boolean = inventoryAt(position, side.orNull).exists(insertIntoInventory(stack, _, limit, simulate)) type Extractor = () => Int @@ -254,7 +260,7 @@ object InventoryUtils { * Utility method for calling extractFromInventory on an inventory * in the world. */ - def getExtractorFromInventoryAt(consumer: (ItemStack) => Unit, position: BlockPosition, side: EnumFacing, limit: Int = 64): Extractor = + def getExtractorFromInventoryAt(consumer: (ItemStack) => Unit, position: BlockPosition, side: Direction, limit: Int = 64): Extractor = inventoryAt(position, side) match { case Some(inventory) => () => extractAnyFromInventory(consumer, inventory, limit) case _ => null @@ -277,7 +283,7 @@ object InventoryUtils { extractAnyFromInventory( insertIntoInventory(_, sink, limit), source, limit = limit) - def transferBetweenInventories(source: IInventory, sourceSide: EnumFacing, sink: IInventory, sinkSide: Option[EnumFacing], limit: Int): Int = + def transferBetweenInventories(source: IInventory, sourceSide: Direction, sink: IInventory, sinkSide: Option[Direction], limit: Int): Int = transferBetweenInventories(asItemHandler(source, sourceSide), asItemHandler(sink, sinkSide.orNull), limit) /** @@ -293,14 +299,14 @@ object InventoryUtils { insertIntoInventory(_, sink, limit), source, sourceSlot, limit = limit) } - def transferBetweenInventoriesSlots(source: IInventory, sourceSide: EnumFacing, sourceSlot: Int, sink: IInventory, sinkSide: Option[EnumFacing], sinkSlot: Option[Int], limit: Int): Int = + def transferBetweenInventoriesSlots(source: IInventory, sourceSide: Direction, sourceSlot: Int, sink: IInventory, sinkSide: Option[Direction], sinkSlot: Option[Int], limit: Int): Int = transferBetweenInventoriesSlots(asItemHandler(source, sourceSide), sourceSlot, asItemHandler(sink, sinkSide.orNull), sinkSlot, limit) /** * Utility method for calling transferBetweenInventories on inventories * in the world. */ - def getTransferBetweenInventoriesAt(source: BlockPosition, sourceSide: EnumFacing, sink: BlockPosition, sinkSide: Option[EnumFacing], limit: Int = 64): Extractor = + def getTransferBetweenInventoriesAt(source: BlockPosition, sourceSide: Direction, sink: BlockPosition, sinkSide: Option[Direction], limit: Int = 64): Extractor = inventoryAt(source, sourceSide) match { case Some(sourceInventory) => inventoryAt(sink, sinkSide.orNull) match { @@ -314,7 +320,7 @@ object InventoryUtils { * Utility method for calling transferBetweenInventoriesSlots on inventories * in the world. */ - def getTransferBetweenInventoriesSlotsAt(sourcePos: BlockPosition, sourceSide: EnumFacing, sourceSlot: Int, sinkPos: BlockPosition, sinkSide: Option[EnumFacing], sinkSlot: Option[Int], limit: Int = 64): Extractor = + def getTransferBetweenInventoriesSlotsAt(sourcePos: BlockPosition, sourceSide: Direction, sourceSlot: Int, sinkPos: BlockPosition, sinkSide: Option[Direction], sinkSlot: Option[Int], limit: Int = 64): Extractor = inventoryAt(sourcePos, sourceSide) match { case Some(sourceInventory) => inventoryAt(sinkPos, sinkSide.orNull) match { @@ -324,12 +330,25 @@ object InventoryUtils { case _ => null } + /** + * Utility method mirroring dropAllSlots but instead piping slots into + * a provided consumer for use with LootContext. + */ + def forAllSlots(inventory: IInventory, dst: Consumer[ItemStack]): Unit = { + for (slot <- 0 until inventory.getContainerSize) { + StackOption(inventory.getItem(slot)) match { + case SomeStack(stack) if stack.getCount > 0 => dst.accept(stack) + case _ => // Nothing. + } + } + } + /** * Utility method for dropping contents from a single inventory slot into * the world. */ - def dropSlot(position: BlockPosition, inventory: IInventory, slot: Int, count: Int, direction: Option[EnumFacing] = None): Boolean = { - StackOption(inventory.decrStackSize(slot, count)) match { + def dropSlot(position: BlockPosition, inventory: IInventory, slot: Int, count: Int, direction: Option[Direction] = None): Boolean = { + StackOption(inventory.removeItem(slot, count)) match { case SomeStack(stack) if stack.getCount > 0 => spawnStackInWorld(position, stack, direction); true case _ => false } @@ -339,10 +358,10 @@ object InventoryUtils { * Utility method for dumping all inventory contents into the world. */ def dropAllSlots(position: BlockPosition, inventory: IInventory): Unit = { - for (slot <- 0 until inventory.getSizeInventory) { - StackOption(inventory.getStackInSlot(slot)) match { + for (slot <- 0 until inventory.getContainerSize) { + StackOption(inventory.getItem(slot)) match { case SomeStack(stack) if stack.getCount > 0 => - inventory.setInventorySlotContents(slot, ItemStack.EMPTY) + inventory.setItem(slot, ItemStack.EMPTY) spawnStackInWorld(position, stack) case _ => // Nothing. } @@ -352,16 +371,16 @@ object InventoryUtils { /** * Try inserting an item stack into a player inventory. If that fails, drop it into the world. */ - def addToPlayerInventory(stack: ItemStack, player: EntityPlayer, spawnInWorld: Boolean = true): Unit = { + def addToPlayerInventory(stack: ItemStack, player: PlayerEntity, spawnInWorld: Boolean = true): Unit = { if (!stack.isEmpty) { - if (player.inventory.addItemStackToInventory(stack)) { - player.inventory.markDirty() - if (player.openContainer != null) { - player.openContainer.detectAndSendChanges() + if (player.inventory.add(stack)) { + player.inventory.setChanged() + if (player.containerMenu != null) { + player.containerMenu.broadcastChanges() } } if (stack.getCount > 0 && spawnInWorld) { - player.dropItem(stack, false, false) + player.drop(stack, false, false) } } } @@ -369,22 +388,23 @@ object InventoryUtils { /** * Utility method for spawning an item stack in the world. */ - def spawnStackInWorld(position: BlockPosition, stack: ItemStack, direction: Option[EnumFacing] = None, validator: Option[EntityItem => Boolean] = None): EntityItem = position.world match { + def spawnStackInWorld(position: BlockPosition, stack: ItemStack, direction: Option[Direction] = None, validator: Option[ItemEntity => Boolean] = None): ItemEntity = position.world match { case Some(world) if !stack.isEmpty && stack.getCount > 0 => - val rng = world.rand - val (ox, oy, oz) = direction.fold((0, 0, 0))(d => (d.getFrontOffsetX, d.getFrontOffsetY, d.getFrontOffsetZ)) + val rng = world.random + val (ox, oy, oz) = direction.fold((0, 0, 0))(d => (d.getStepX, d.getStepY, d.getStepZ)) val (tx, ty, tz) = ( 0.1 * (rng.nextDouble - 0.5) + ox * 0.65, 0.1 * (rng.nextDouble - 0.5) + oy * 0.75 + (ox + oz) * 0.25, 0.1 * (rng.nextDouble - 0.5) + oz * 0.65) val dropPos = position.offset(0.5 + tx, 0.5 + ty, 0.5 + tz) - val entity = new EntityItem(world, dropPos.x, dropPos.y, dropPos.z, stack.copy()) - entity.motionX = 0.0125 * (rng.nextDouble - 0.5) + ox * 0.03 - entity.motionY = 0.0125 * (rng.nextDouble - 0.5) + oy * 0.08 + (ox + oz) * 0.03 - entity.motionZ = 0.0125 * (rng.nextDouble - 0.5) + oz * 0.03 + val entity = new ItemEntity(world, dropPos.x, dropPos.y, dropPos.z, stack.copy()) + entity.setDeltaMovement(new Vector3d( + 0.0125 * (rng.nextDouble - 0.5) + ox * 0.03, + 0.0125 * (rng.nextDouble - 0.5) + oy * 0.08 + (ox + oz) * 0.03, + 0.0125 * (rng.nextDouble - 0.5) + oz * 0.03)) if (validator.fold(true)(_ (entity))) { - entity.setPickupDelay(15) - world.spawnEntity(entity) + entity.setPickUpDelay(15) + world.addFreshEntity(entity) entity } else null diff --git a/src/main/scala/li/cil/oc/util/ItemColorizer.scala b/src/main/scala/li/cil/oc/util/ItemColorizer.scala index 7043d29ced..40525013c9 100644 --- a/src/main/scala/li/cil/oc/util/ItemColorizer.scala +++ b/src/main/scala/li/cil/oc/util/ItemColorizer.scala @@ -1,7 +1,7 @@ package li.cil.oc.util import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT /** * @author asie, Vexatos @@ -10,38 +10,34 @@ object ItemColorizer { /** * Return whether the specified armor ItemStack has a color. */ - def hasColor(stack: ItemStack): Boolean = stack.hasTagCompound && stack.getTagCompound.hasKey("display") && stack.getTagCompound.getCompoundTag("display").hasKey("color") + def hasColor(stack: ItemStack): Boolean = stack.hasTag && stack.getTag.contains("display") && stack.getTag.getCompound("display").contains("color") /** * Return the color for the specified armor ItemStack. */ def getColor(stack: ItemStack): Int = { - val tag = stack.getTagCompound + val tag = stack.getTag if (tag != null) { - val displayTag = tag.getCompoundTag("display") - if (displayTag == null) -1 else if (displayTag.hasKey("color")) displayTag.getInteger("color") else -1 + if (tag.contains("display")) { + val displayTag = tag.getCompound("display") + if (displayTag.contains("color")) displayTag.getInt("color") else -1 + } + else -1 } else -1 } def removeColor(stack: ItemStack) { - val tag = stack.getTagCompound + val tag = stack.getTag if (tag != null) { - val displayTag = tag.getCompoundTag("display") - if (displayTag.hasKey("color")) displayTag.removeTag("color") + val displayTag = tag.getCompound("display") + if (displayTag.contains("color")) displayTag.remove("color") + if (displayTag.isEmpty) tag.remove("display") + if (tag.isEmpty) stack.setTag(null) } } def setColor(stack: ItemStack, color: Int) { - var tag = stack.getTagCompound - if (tag == null) { - tag = new NBTTagCompound - stack.setTagCompound(tag) - } - val displayTag = tag.getCompoundTag("display") - if (!tag.hasKey("display")) { - tag.setTag("display", displayTag) - } - displayTag.setInteger("color", color) + stack.getOrCreateTagElement("display").putInt("color", color) } } diff --git a/src/main/scala/li/cil/oc/util/ItemStackWrapper.scala b/src/main/scala/li/cil/oc/util/ItemStackWrapper.scala index 939682bdae..8b62dae8ff 100644 --- a/src/main/scala/li/cil/oc/util/ItemStackWrapper.scala +++ b/src/main/scala/li/cil/oc/util/ItemStackWrapper.scala @@ -8,9 +8,9 @@ import net.minecraft.item.ItemStack import scala.language.implicitConversions class ItemStackWrapper(val inner: ItemStack) extends Ordered[ItemStackWrapper] { - def id = if (inner.getItem != null) Item.getIdFromItem(inner.getItem) else 0 + def id = if (inner.getItem != null) Item.getId(inner.getItem) else 0 - def damage = if (inner.getItem != null) inner.getItemDamage else 0 + def damage = if (inner.getItem != null) inner.getDamageValue else 0 override def compare(that: ItemStackWrapper) = { if (this.id == that.id) this.damage - that.damage diff --git a/src/main/scala/li/cil/oc/util/ItemUtils.scala b/src/main/scala/li/cil/oc/util/ItemUtils.scala index 80a1100ea2..8eaf72bcd0 100644 --- a/src/main/scala/li/cil/oc/util/ItemUtils.scala +++ b/src/main/scala/li/cil/oc/util/ItemUtils.scala @@ -11,37 +11,39 @@ import li.cil.oc.api import li.cil.oc.common.Tier import net.minecraft.block.Block import net.minecraft.item.Item -import net.minecraft.item.ItemBlock -import net.minecraft.item.ItemBucket +import net.minecraft.item.BlockItem +import net.minecraft.item.BucketItem import net.minecraft.item.ItemStack -import net.minecraft.item.crafting.CraftingManager +import net.minecraft.item.crafting.RecipeManager +import net.minecraft.item.crafting.ICraftingRecipe import net.minecraft.item.crafting.IRecipe +import net.minecraft.item.crafting.IRecipeType import net.minecraft.item.crafting.Ingredient -import net.minecraft.item.crafting.ShapedRecipes -import net.minecraft.item.crafting.ShapelessRecipes +import net.minecraft.item.crafting.ShapedRecipe +import net.minecraft.item.crafting.ShapelessRecipe +import net.minecraft.inventory.CraftingInventory import net.minecraft.nbt.CompressedStreamTools -import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.oredict.ShapedOreRecipe -import net.minecraftforge.oredict.ShapelessOreRecipe +import net.minecraft.nbt.CompoundNBT +import net.minecraftforge.registries.ForgeRegistries -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable object ItemUtils { - def getDisplayName(nbt: NBTTagCompound): Option[String] = { - if (nbt.hasKey("display")) { - val displayNbt = nbt.getCompoundTag("display") - if (displayNbt.hasKey("Name")) + def getDisplayName(nbt: CompoundNBT): Option[String] = { + if (nbt.contains("display")) { + val displayNbt = nbt.getCompound("display") + if (displayNbt.contains("Name")) return Option(displayNbt.getString("Name")) } None } - def setDisplayName(nbt: NBTTagCompound, name: String): Unit = { - if (!nbt.hasKey("display")) { - nbt.setTag("display", new NBTTagCompound()) + def setDisplayName(nbt: CompoundNBT, name: String): Unit = { + if (!nbt.contains("display")) { + nbt.put("display", new CompoundNBT()) } - nbt.getCompoundTag("display").setString("Name", name) + nbt.getCompound("display").putString("Name", name) } def caseTier(stack: ItemStack): Int = { @@ -68,46 +70,44 @@ object ItemUtils { def caseNameWithTierSuffix(name: String, tier: Int): String = name + (if (tier == Tier.Four) "creative" else (tier + 1).toString) - def loadTag(data: Array[Byte]): NBTTagCompound = { + def loadTag(data: Array[Byte]): CompoundNBT = { val bais = new ByteArrayInputStream(data) CompressedStreamTools.readCompressed(bais) } def saveStack(stack: ItemStack): Array[Byte] = { - val tag = new NBTTagCompound() - stack.writeToNBT(tag) + val tag = new CompoundNBT() + stack.save(tag) saveTag(tag) } - def saveTag(tag: NBTTagCompound): Array[Byte] = { + def saveTag(tag: CompoundNBT): Array[Byte] = { val baos = new ByteArrayOutputStream() CompressedStreamTools.writeCompressed(tag, baos) baos.toByteArray } - def getIngredients(stack: ItemStack): Array[ItemStack] = try { + def getIngredients(manager: RecipeManager, stack: ItemStack): Array[ItemStack] = try { def getFilteredInputs(inputs: Iterable[ItemStack], outputSize: Int) = (inputs.filter(input => !input.isEmpty && input.getCount / outputSize > 0 && // Strip out buckets, because those are returned when crafting, and // we have no way of returning the fluid only (and I can't be arsed // to make it output fluids into fluiducts or such, sorry). - !input.getItem.isInstanceOf[ItemBucket]).toArray, outputSize) + !input.getItem.isInstanceOf[BucketItem]).toArray, outputSize) - def getOutputSize(recipe: IRecipe) = recipe.getRecipeOutput.getCount + def getOutputSize(recipe: IRecipe[_]) = recipe.getResultItem.getCount def isInputBlacklisted(stack: ItemStack) = stack.getItem match { - case item: ItemBlock => Settings.get.disassemblerInputBlacklist.contains(Block.REGISTRY.getNameForObject(item.getBlock)) - case item: Item => Settings.get.disassemblerInputBlacklist.contains(Item.REGISTRY.getNameForObject(item)) + case item: BlockItem => Settings.get.disassemblerInputBlacklist.contains(ForgeRegistries.BLOCKS.getKey(item.getBlock)) + case item: Item => Settings.get.disassemblerInputBlacklist.contains(ForgeRegistries.ITEMS.getKey(item)) case _ => false } - val (ingredients, count) = CraftingManager.REGISTRY. - filter(recipe => !recipe.getRecipeOutput.isEmpty && recipe.getRecipeOutput.isItemEqual(stack)).collect { - case recipe: ShapedRecipes => getFilteredInputs(resolveOreDictEntries(recipe.recipeItems), getOutputSize(recipe)) - case recipe: ShapelessRecipes => getFilteredInputs(resolveOreDictEntries(recipe.recipeItems), getOutputSize(recipe)) - case recipe: ShapedOreRecipe => getFilteredInputs(resolveOreDictEntries(recipe.getIngredients), getOutputSize(recipe)) - case recipe: ShapelessOreRecipe => getFilteredInputs(resolveOreDictEntries(recipe.getIngredients), getOutputSize(recipe)) + val (ingredients, count) = manager.getAllRecipesFor[CraftingInventory, ICraftingRecipe](IRecipeType.CRAFTING). + filter(recipe => !recipe.getResultItem.isEmpty && recipe.getResultItem.sameItem(stack)).collect { + case recipe: ShapedRecipe => getFilteredInputs(resolveOreDictEntries(recipe.getIngredients), getOutputSize(recipe)) + case recipe: ShapelessRecipe => getFilteredInputs(resolveOreDictEntries(recipe.getIngredients), getOutputSize(recipe)) }.collectFirst { case (inputs, outputSize) if !inputs.exists(isInputBlacklisted) => (inputs, outputSize) } match { @@ -116,13 +116,13 @@ object ItemUtils { } // Avoid positive feedback loops. - if (ingredients.exists(ingredient => ingredient.isItemEqual(stack))) { + if (ingredients.exists(ingredient => ingredient.sameItem(stack))) { return Array.empty[ItemStack] } // Merge equal items for size division by output size. val merged = mutable.ArrayBuffer.empty[ItemStack] for (ingredient <- ingredients) { - merged.find(_.isItemEqual(ingredient)) match { + merged.find(_.sameItem(ingredient)) match { case Some(entry) => entry.grow(ingredient.getCount) case _ => merged += ingredient.copy() } @@ -148,7 +148,7 @@ object ItemUtils { private lazy val rng = new Random() private def resolveOreDictEntries[T](entries: Iterable[Ingredient]) = entries.collect { - case ing: Ingredient if ing.getMatchingStacks.nonEmpty => ing.getMatchingStacks()(rng.nextInt(ing.getMatchingStacks.length)) + case ing: Ingredient if ing.getItems.nonEmpty => ing.getItems()(rng.nextInt(ing.getItems.length)) } } diff --git a/src/main/scala/li/cil/oc/util/NbtDataStream.scala b/src/main/scala/li/cil/oc/util/NbtDataStream.scala index 29c4de9115..80110926df 100644 --- a/src/main/scala/li/cil/oc/util/NbtDataStream.scala +++ b/src/main/scala/li/cil/oc/util/NbtDataStream.scala @@ -1,10 +1,10 @@ package li.cil.oc.util -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT object NbtDataStream { - def getShortArray(nbt: NBTTagCompound, key: String, array2d: Array[Array[Short]], w: Int, h: Int) : Boolean = { - if (!nbt.hasKey(key)) { + def getShortArray(nbt: CompoundNBT, key: String, array2d: Array[Array[Short]], w: Int, h: Int) : Boolean = { + if (!nbt.contains(key)) { return false } @@ -21,8 +21,8 @@ object NbtDataStream { true } - def getIntArrayLegacy(nbt: NBTTagCompound, key: String, array2d: Array[Array[Short]], w: Int, h: Int) : Boolean = { - if (!nbt.hasKey(key)) { + def getIntArrayLegacy(nbt: CompoundNBT, key: String, array2d: Array[Array[Short]], w: Int, h: Int) : Boolean = { + if (!nbt.contains(key)) { return false } // legacy format @@ -40,15 +40,15 @@ object NbtDataStream { true } - def setShortArray(nbt: NBTTagCompound, key: String, array: Array[Short]): Unit = { + def setShortArray(nbt: CompoundNBT, key: String, array: Array[Short]): Unit = { val rawByteWriter = new java.io.ByteArrayOutputStream() val memWriter = new java.io.DataOutputStream(rawByteWriter) array.foreach(memWriter.writeShort(_)) - nbt.setByteArray(key, rawByteWriter.toByteArray) + nbt.putByteArray(key, rawByteWriter.toByteArray) } - def getOptBoolean(nbt: NBTTagCompound, key: String, df: Boolean): Boolean = if (nbt.hasKey(key)) nbt.getBoolean(key) else df - def getOptString(nbt: NBTTagCompound, key: String, df: String): String = if (nbt.hasKey(key)) nbt.getString(key) else df - def getOptNbt(nbt: NBTTagCompound, key: String): NBTTagCompound = if (nbt.hasKey(key)) nbt.getCompoundTag(key) else new NBTTagCompound - def getOptInt(nbt: NBTTagCompound, key: String, df: Int): Int = if (nbt.hasKey(key)) nbt.getInteger(key) else df + def getOptBoolean(nbt: CompoundNBT, key: String, df: Boolean): Boolean = if (nbt.contains(key)) nbt.getBoolean(key) else df + def getOptString(nbt: CompoundNBT, key: String, df: String): String = if (nbt.contains(key)) nbt.getString(key) else df + def getOptNbt(nbt: CompoundNBT, key: String): CompoundNBT = if (nbt.contains(key)) nbt.getCompound(key) else new CompoundNBT + def getOptInt(nbt: CompoundNBT, key: String, df: Int): Int = if (nbt.contains(key)) nbt.getInt(key) else df } diff --git a/src/main/scala/li/cil/oc/util/OldScaledResolution.java b/src/main/scala/li/cil/oc/util/OldScaledResolution.java deleted file mode 100644 index 14b9cce066..0000000000 --- a/src/main/scala/li/cil/oc/util/OldScaledResolution.java +++ /dev/null @@ -1,37 +0,0 @@ -package li.cil.oc.util; - -import net.minecraft.client.Minecraft; -import net.minecraft.util.math.MathHelper; - -public class OldScaledResolution { - private final int scaledWidth; - private final int scaledHeight; - - public OldScaledResolution(Minecraft minecraft, int width, int height) { - int scaleFactor = 1; - int guiScale = minecraft.gameSettings.guiScale; - - if (guiScale == 0) { - guiScale = 1000; - } - - while (scaleFactor < guiScale && width / (scaleFactor + 1) >= 320 && height / (scaleFactor + 1) >= 240) { - ++scaleFactor; - } - - if (minecraft.isUnicode() && scaleFactor % 2 != 0 && scaleFactor != 1) { - --scaleFactor; - } - - this.scaledWidth = MathHelper.ceil((double) width / (double) scaleFactor); - this.scaledHeight = MathHelper.ceil((double) height / (double) scaleFactor); - } - - public int getScaledWidth() { - return this.scaledWidth; - } - - public int getScaledHeight() { - return this.scaledHeight; - } -} diff --git a/src/main/scala/li/cil/oc/util/PackedColor.scala b/src/main/scala/li/cil/oc/util/PackedColor.scala index 7714986153..6d532ceafe 100644 --- a/src/main/scala/li/cil/oc/util/PackedColor.scala +++ b/src/main/scala/li/cil/oc/util/PackedColor.scala @@ -3,7 +3,7 @@ package li.cil.oc.util import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.Persistable -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT object PackedColor { @@ -47,9 +47,9 @@ object PackedColor { def isFromPalette(value: Int): Boolean = false - override def load(nbt: NBTTagCompound) {} + override def loadData(nbt: CompoundNBT) {} - override def save(nbt: NBTTagCompound) {} + override def saveData(nbt: CompoundNBT) {} } class SingleBitFormat(val color: Int) extends ColorFormat { @@ -104,13 +104,13 @@ object PackedColor { 0xCCCCCC, 0x336699, 0x9933CC, 0x333399, 0x663300, 0x336600, 0xFF3333, 0x000000) - override def load(nbt: NBTTagCompound) { + override def loadData(nbt: CompoundNBT) { val loaded = nbt.getIntArray("palette") Array.copy(loaded, 0, palette, 0, math.min(loaded.length, palette.length)) } - override def save(nbt: NBTTagCompound) { - nbt.setIntArray("palette", palette) + override def saveData(nbt: CompoundNBT) { + nbt.putIntArray("palette", palette) } } diff --git a/src/main/scala/li/cil/oc/util/PlayerUtils.scala b/src/main/scala/li/cil/oc/util/PlayerUtils.scala index 6f24c64dc5..c26e027545 100644 --- a/src/main/scala/li/cil/oc/util/PlayerUtils.scala +++ b/src/main/scala/li/cil/oc/util/PlayerUtils.scala @@ -1,26 +1,26 @@ package li.cil.oc.util -import net.minecraft.entity.player.EntityPlayer -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.util.EnumParticleTypes +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.nbt.CompoundNBT +import net.minecraft.particles.IParticleData object PlayerUtils { - def persistedData(player: EntityPlayer): NBTTagCompound = { - val nbt = player.getEntityData - if (!nbt.hasKey(EntityPlayer.PERSISTED_NBT_TAG)) { - nbt.setTag(EntityPlayer.PERSISTED_NBT_TAG, new NBTTagCompound()) + def persistedData(player: PlayerEntity): CompoundNBT = { + val nbt = player.getPersistentData + if (!nbt.contains(PlayerEntity.PERSISTED_NBT_TAG)) { + nbt.put(PlayerEntity.PERSISTED_NBT_TAG, new CompoundNBT()) } - nbt.getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG) + nbt.getCompound(PlayerEntity.PERSISTED_NBT_TAG) } - def spawnParticleAround(player: EntityPlayer, effectType: EnumParticleTypes, chance: Double = 1.0): Unit = { - val rng = player.getEntityWorld.rand + def spawnParticleAround(player: PlayerEntity, effectType: IParticleData, chance: Double = 1.0): Unit = { + val rng = player.level.random if (chance >= 1 || rng.nextDouble() < chance) { - val bounds = player.getEntityBoundingBox + val bounds = player.getBoundingBox val x = bounds.minX + (bounds.maxX - bounds.minX) * rng.nextDouble() * 1.5 val y = bounds.minY + (bounds.maxY - bounds.minY) * rng.nextDouble() * 0.5 val z = bounds.minZ + (bounds.maxZ - bounds.minZ) * rng.nextDouble() * 1.5 - player.getEntityWorld.spawnParticle(effectType, x, y, z, 0, 0, 0) + player.level.addParticle(effectType, x, y, z, 0, 0, 0) } } } diff --git a/src/main/scala/li/cil/oc/util/Rarity.scala b/src/main/scala/li/cil/oc/util/Rarity.scala index 428461ea64..46ee454077 100644 --- a/src/main/scala/li/cil/oc/util/Rarity.scala +++ b/src/main/scala/li/cil/oc/util/Rarity.scala @@ -1,9 +1,10 @@ package li.cil.oc.util -import net.minecraft.item.EnumRarity +import net.minecraft.item.{Rarity => _Rarity} object Rarity { - private val lookup = Array(EnumRarity.COMMON, EnumRarity.UNCOMMON, EnumRarity.RARE, EnumRarity.EPIC) + import _Rarity._ + private val lookup = Array(_Rarity.COMMON, _Rarity.UNCOMMON, _Rarity.RARE, _Rarity.EPIC) def byTier(tier: Int) = lookup(tier max 0 min (lookup.length - 1)) } diff --git a/src/main/scala/li/cil/oc/util/RenderState.scala b/src/main/scala/li/cil/oc/util/RenderState.scala index 03d64058fc..65be1dbe65 100644 --- a/src/main/scala/li/cil/oc/util/RenderState.scala +++ b/src/main/scala/li/cil/oc/util/RenderState.scala @@ -1,16 +1,14 @@ package li.cil.oc.util +import com.mojang.blaze3d.systems.RenderSystem import li.cil.oc.OpenComputers import li.cil.oc.Settings import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.client.renderer.GlStateManager.CullFace import net.minecraft.client.renderer.RenderHelper import org.lwjgl.opengl._ -import org.lwjgl.util.glu.GLU -// This class has evolved into a wrapper for GlStateManager that basically does -// nothing but call the corresponding GlStateManager methods and then also +// This class has evolved into a wrapper for RenderSystem that basically does +// nothing but call the corresponding RenderSystem methods and then also // forcefully applies whatever that call *should* do. This way the state // manager's internal state is kept up-to-date but we also avoid issues with // that state being incorrect causing wrong behavior (I've had too many render @@ -18,12 +16,21 @@ import org.lwjgl.util.glu.GLU // because the state manager thought it already was in the state to change to, // so I frankly don't care if this is less performant anymore). object RenderState { - val arb = GLContext.getCapabilities.GL_ARB_multitexture && !GLContext.getCapabilities.OpenGL13 + def getErrorString(errorCode: Int): String = errorCode match { + case GL11.GL_NO_ERROR => "No error" + case GL11.GL_INVALID_ENUM => "Enum argument out of range" + case GL11.GL_INVALID_VALUE => "Numeric argument out of range" + case GL11.GL_INVALID_OPERATION => "Operation illegal in current state" + case GL11.GL_STACK_OVERFLOW => "Command would cause a stack overflow" + case GL11.GL_STACK_UNDERFLOW => "Command would cause a stack underflow" + case GL11.GL_OUT_OF_MEMORY => "Not enough memory left to execute command" + case _ => f"Unknown [0x$errorCode%X]" + } def checkError(where: String) { val error = GL11.glGetError if (error != 0 && Settings.get.logOpenGLErrors) { - OpenComputers.log.warn("GL ERROR @ " + where + ": " + GLU.gluErrorString(error)) + OpenComputers.log.warn("GL ERROR @ " + where + ": " + getErrorString(error)) } } @@ -35,52 +42,46 @@ object RenderState { else false } - // pushAttrib/popAttrib currently breaks the GlStateManager because it doesn't + // pushAttrib/popAttrib currently breaks the RenderSystem because it doesn't // accordingly pushes/pops its cache, so it gets into an illegal state... // See https://gist.github.com/fnuecke/9a5b2499835fca9b52419277dc6239ca def pushAttrib(): Unit = { -// GlStateManager.glPushAttrib(mask) +// RenderSystem.glPushAttrib(mask) } def popAttrib(): Unit = { -// GlStateManager.popAttrib() +// RenderSystem.popAttrib() } def disableEntityLighting() { - Minecraft.getMinecraft.entityRenderer.disableLightmap() - GlStateManager.disableLighting() - GlStateManager.disableLight(0) - GlStateManager.disableLight(1) - GlStateManager.disableColorMaterial() + RenderSystem.disableLighting() + RenderSystem.disableColorMaterial() } def enableEntityLighting() { - Minecraft.getMinecraft.entityRenderer.enableLightmap() - GlStateManager.enableLighting() - GlStateManager.enableLight(0) - GlStateManager.enableLight(1) - GlStateManager.enableColorMaterial() + RenderSystem.enableLighting() + RenderSystem.enableColorMaterial() } def makeItBlend() { - GlStateManager.enableBlend() + RenderSystem.enableBlend() GL11.glEnable(GL11.GL_BLEND) - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA) + RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA) } def disableBlend() { - GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_ZERO) - GlStateManager.disableBlend() + RenderSystem.blendFunc(GL11.GL_ONE, GL11.GL_ZERO) + RenderSystem.disableBlend() GL11.glDisable(GL11.GL_BLEND) } def setBlendAlpha(alpha: Float) = { - GlStateManager.color(1, 1, 1, alpha) - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) + RenderSystem.color4f(1, 1, 1, alpha) + RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE) } def bindTexture(id: Int): Unit = { - GlStateManager.bindTexture(id) + RenderSystem.bindTexture(id) GL11.glBindTexture(GL11.GL_TEXTURE_2D, id) } } diff --git a/src/main/scala/li/cil/oc/util/ResultWrapper.scala b/src/main/scala/li/cil/oc/util/ResultWrapper.scala index fc844b560a..cb06793282 100644 --- a/src/main/scala/li/cil/oc/util/ResultWrapper.scala +++ b/src/main/scala/li/cil/oc/util/ResultWrapper.scala @@ -5,6 +5,8 @@ import net.minecraft.item.ItemStack import scala.math.ScalaNumber object ResultWrapper { + final val unit = ().asInstanceOf[AnyRef] + def result(args: Any*): Array[AnyRef] = { def unwrap(arg: Any): AnyRef = arg match { case x: ScalaNumber => x.underlying diff --git a/src/main/scala/li/cil/oc/util/RotationHelper.scala b/src/main/scala/li/cil/oc/util/RotationHelper.scala index 8eb8ee6e3c..46fba888eb 100644 --- a/src/main/scala/li/cil/oc/util/RotationHelper.scala +++ b/src/main/scala/li/cil/oc/util/RotationHelper.scala @@ -1,46 +1,48 @@ package li.cil.oc.util -import net.minecraft.util.EnumFacing +import net.minecraft.util.Direction import scala.collection.mutable object RotationHelper { + private val DIRECTIONS = Direction.values + + def getNumDirections = DIRECTIONS.length + + def getFront(index: Int): Direction = DIRECTIONS(Math.floorMod(index, DIRECTIONS.length)) + def fromYaw(yaw: Float) = { (yaw / 360 * 4).round & 3 match { - case 0 => EnumFacing.SOUTH - case 1 => EnumFacing.WEST - case 2 => EnumFacing.NORTH - case 3 => EnumFacing.EAST + case 0 => Direction.SOUTH + case 1 => Direction.WEST + case 2 => Direction.NORTH + case 3 => Direction.EAST } } - def toLocal(pitch: EnumFacing, yaw: EnumFacing, value: EnumFacing) = + def toLocal(pitch: Direction, yaw: Direction, value: Direction) = translationFor(pitch, yaw)(value.ordinal) - def toGlobal(pitch: EnumFacing, yaw: EnumFacing, value: EnumFacing) = + def toGlobal(pitch: Direction, yaw: Direction, value: Direction) = inverseTranslationFor(pitch, yaw)(value.ordinal) - def translationFor(pitch: EnumFacing, yaw: EnumFacing) = + def translationFor(pitch: Direction, yaw: Direction) = translationCache.synchronized(translationCache. getOrElseUpdate(pitch, mutable.Map.empty). getOrElseUpdate(yaw, translations(pitch.ordinal)(yaw.ordinal - 2))) - def inverseTranslationFor(pitch: EnumFacing, yaw: EnumFacing) = + def inverseTranslationFor(pitch: Direction, yaw: Direction) = inverseTranslationCache.synchronized(inverseTranslationCache. getOrElseUpdate(pitch, mutable.Map.empty). getOrElseUpdate(yaw, { val t = translationFor(pitch, yaw) - t.indices. - map(EnumFacing.getFront). - map(t.indexOf). - map(EnumFacing.getFront). - toArray + t.indices.map(Direction.from3DDataValue).map(t.indexOf(_)).map(Direction.from3DDataValue).toArray })) // ----------------------------------------------------------------------- // - private val translationCache = mutable.Map.empty[EnumFacing, mutable.Map[EnumFacing, Array[EnumFacing]]] - private val inverseTranslationCache = mutable.Map.empty[EnumFacing, mutable.Map[EnumFacing, Array[EnumFacing]]] + private val translationCache = mutable.Map.empty[Direction, mutable.Map[Direction, Array[Direction]]] + private val inverseTranslationCache = mutable.Map.empty[Direction, mutable.Map[Direction, Array[Direction]]] /** * Translates forge directions based on the block's pitch and yaw. The base @@ -82,12 +84,12 @@ object RotationHelper { /** Shortcuts for forge directions to make the above more readable. */ private object D { - val down = EnumFacing.DOWN - val up = EnumFacing.UP - val north = EnumFacing.NORTH - val south = EnumFacing.SOUTH - val west = EnumFacing.WEST - val east = EnumFacing.EAST + val down = Direction.DOWN + val up = Direction.UP + val north = Direction.NORTH + val south = Direction.SOUTH + val west = Direction.WEST + val east = Direction.EAST } } diff --git a/src/main/scala/li/cil/oc/util/ScalaClosure.scala b/src/main/scala/li/cil/oc/util/ScalaClosure.scala index 801003f7c7..33955e137d 100644 --- a/src/main/scala/li/cil/oc/util/ScalaClosure.scala +++ b/src/main/scala/li/cil/oc/util/ScalaClosure.scala @@ -8,7 +8,7 @@ import li.cil.repack.org.luaj.vm2.LuaValue import li.cil.repack.org.luaj.vm2.Varargs import li.cil.repack.org.luaj.vm2.lib.VarArgFunction -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToScala._ import scala.collection.mutable import scala.language.implicitConversions import scala.math.ScalaNumber @@ -34,7 +34,7 @@ object ScalaClosure { case null => null case primitive => primitive.asInstanceOf[AnyRef] }) match { - case null | Unit | _: BoxedUnit => LuaValue.NIL + case null | () | _: BoxedUnit => LuaValue.NIL case value: java.lang.Boolean => LuaValue.valueOf(value.booleanValue) case value: java.lang.Byte => LuaValue.valueOf(value.byteValue) case value: java.lang.Character => LuaValue.valueOf(String.valueOf(value)) @@ -64,7 +64,7 @@ object ScalaClosure { table } - def toLuaTable(value: Map[_, _]): LuaValue = { + def toLuaTable[K, V](value: Map[K, V]): LuaValue = { LuaValue.tableOf(value.flatMap { case (k, v) => Seq(toLuaValue(k), toLuaValue(v)) }.toArray) diff --git a/src/main/scala/li/cil/oc/util/TextBuffer.scala b/src/main/scala/li/cil/oc/util/TextBuffer.scala index ce4393a47f..5751101f4f 100644 --- a/src/main/scala/li/cil/oc/util/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/util/TextBuffer.scala @@ -251,45 +251,45 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col } } - def load(nbt: NBTTagCompound): Unit = { + def loadData(nbt: CompoundNBT): Unit = { val maxResolution = math.max(Settings.screenResolutionsByTier.last._1, Settings.screenResolutionsByTier.last._2) - val w = nbt.getInteger("width") min maxResolution max 1 - val h = nbt.getInteger("height") min maxResolution max 1 + val w = nbt.getInt("width") min maxResolution max 1 + val h = nbt.getInt("height") min maxResolution max 1 size = (w, h) - val b = nbt.getTagList("buffer", NBT.TAG_STRING) - for (i <- 0 until math.min(h, b.tagCount)) { - val value = b.getStringTagAt(i) + val b = nbt.getList("buffer", NBT.TAG_STRING) + for (i <- 0 until math.min(h, b.size)) { + val value = b.getString(i) System.arraycopy(value.toCharArray, 0, buffer(i), 0, math.min(value.length, buffer(i).length)) } - val depth = api.internal.TextBuffer.ColorDepth.values.apply(nbt.getInteger("depth") min (api.internal.TextBuffer.ColorDepth.values.length - 1) max 0) + val depth = api.internal.TextBuffer.ColorDepth.values.apply(nbt.getInt("depth") min (api.internal.TextBuffer.ColorDepth.values.length - 1) max 0) _format = PackedColor.Depth.format(depth) - _format.load(nbt) - foreground = PackedColor.Color(nbt.getInteger("foreground"), nbt.getBoolean("foregroundIsPalette")) - background = PackedColor.Color(nbt.getInteger("background"), nbt.getBoolean("backgroundIsPalette")) + _format.loadData(nbt) + foreground = PackedColor.Color(nbt.getInt("foreground"), nbt.getBoolean("foregroundIsPalette")) + background = PackedColor.Color(nbt.getInt("background"), nbt.getBoolean("backgroundIsPalette")) if (!NbtDataStream.getShortArray(nbt, "colors", color, w, h)) { NbtDataStream.getIntArrayLegacy(nbt, "color", color, w, h) } } - def save(nbt: NBTTagCompound): Unit = { - nbt.setInteger("width", width) - nbt.setInteger("height", height) + def saveData(nbt: CompoundNBT): Unit = { + nbt.putInt("width", width) + nbt.putInt("height", height) - val b = new NBTTagList() + val b = new ListNBT() for (i <- 0 until height) { - b.appendTag(new NBTTagString(String.valueOf(buffer(i)))) + b.add(StringNBT.valueOf(String.valueOf(buffer(i)))) } - nbt.setTag("buffer", b) - - nbt.setInteger("depth", _format.depth.ordinal) - _format.save(nbt) - nbt.setInteger("foreground", _foreground.value) - nbt.setBoolean("foregroundIsPalette", _foreground.isPalette) - nbt.setInteger("background", _background.value) - nbt.setBoolean("backgroundIsPalette", _background.isPalette) + nbt.put("buffer", b) + + nbt.putInt("depth", _format.depth.ordinal) + _format.saveData(nbt) + nbt.putInt("foreground", _foreground.value) + nbt.putBoolean("foregroundIsPalette", _foreground.isPalette) + nbt.putInt("background", _background.value) + nbt.putBoolean("backgroundIsPalette", _background.isPalette) NbtDataStream.setShortArray(nbt, "colors", color.flatten.map(_.toShort)) } diff --git a/src/main/scala/li/cil/oc/util/ThreadPoolFactory.scala b/src/main/scala/li/cil/oc/util/ThreadPoolFactory.scala index 9c22b02b1c..2805d6b31a 100644 --- a/src/main/scala/li/cil/oc/util/ThreadPoolFactory.scala +++ b/src/main/scala/li/cil/oc/util/ThreadPoolFactory.scala @@ -9,6 +9,11 @@ import java.util.concurrent.atomic.AtomicInteger import li.cil.oc.OpenComputers import li.cil.oc.Settings +import li.cil.oc.common.SaveHandler +import li.cil.oc.server.fs.Buffered +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent +import net.minecraftforge.fml.event.server.FMLServerStoppedEvent import scala.collection.mutable @@ -19,6 +24,19 @@ object ThreadPoolFactory { else custom max Thread.MIN_PRIORITY min Thread.MAX_PRIORITY } + @SubscribeEvent + def serverStart(e: FMLServerAboutToStartEvent): Unit = { + // Access these handles to ensure the pools actually exist. + SaveHandler.stateSaveHandler + Buffered.fileSaveHandler + ThreadPoolFactory.safePools.foreach(_.newThreadPool()) + } + + @SubscribeEvent + def serverStop(e: FMLServerStoppedEvent): Unit = { + ThreadPoolFactory.safePools.foreach(_.waitForCompletion()) + } + def create(name: String, threads: Int) = Executors.newScheduledThreadPool(threads, new ThreadFactory() { private val baseName = "OpenComputers-" + name + "-" diff --git a/src/main/scala/li/cil/oc/util/Tooltip.scala b/src/main/scala/li/cil/oc/util/Tooltip.scala index 7ec02a735e..b4debf5004 100644 --- a/src/main/scala/li/cil/oc/util/Tooltip.scala +++ b/src/main/scala/li/cil/oc/util/Tooltip.scala @@ -4,14 +4,20 @@ import li.cil.oc.Localization import li.cil.oc.Settings import li.cil.oc.client.KeyBindings import net.minecraft.client.Minecraft +import net.minecraft.client.gui.FontRenderer +import net.minecraft.util.text.CharacterManager.ISliceAcceptor +import net.minecraft.util.text.Style +import net.minecraft.util.text.TextFormatting -import scala.collection.convert.WrapAsJava._ -import scala.collection.convert.WrapAsScala._ +import scala.collection.convert.ImplicitConversionsToJava._ +import scala.collection.convert.ImplicitConversionsToScala._ object Tooltip { private val maxWidth = 220 - private def font = Minecraft.getMinecraft.fontRenderer + private def font = Minecraft.getInstance.font + + val DefaultStyle = Style.EMPTY.applyFormat(TextFormatting.GRAY) def get(name: String, args: Any*): java.util.List[String] = { if (!Localization.canLocalize(Settings.namespace + "tooltip." + name)) return Seq.empty[String] @@ -19,14 +25,14 @@ object Tooltip { format(args.map(_.toString): _*) if (font == null) return tooltip.lines.toList // Some mods request tooltips before font renderer is available. val isSubTooltip = name.contains(".") - val shouldShorten = (isSubTooltip || font.getStringWidth(tooltip) > maxWidth) && !KeyBindings.showExtendedTooltips + val shouldShorten = (isSubTooltip || font.width(tooltip) > maxWidth) && !KeyBindings.showExtendedTooltips if (shouldShorten) { if (isSubTooltip) Seq.empty[String] else Seq(Localization.localizeImmediately("tooltip.toolong", KeyBindings.getKeyBindingName(KeyBindings.extendedTooltip))) } else tooltip. lines. - map(font.listFormattedStringToWidth(_, maxWidth).map(_.asInstanceOf[String].trim() + " ")). + map(wrap(font, _, maxWidth).map(_.asInstanceOf[String].trim() + " ")). flatten. toList } @@ -36,9 +42,17 @@ object Tooltip { Localization.localizeImmediately("tooltip." + name). format(args.map(_.toString): _*). lines. - map(font.listFormattedStringToWidth(_, maxWidth).map(_.asInstanceOf[String].trim() + " ")). + map(wrap(font, _, maxWidth).map(_.asInstanceOf[String].trim() + " ")). flatten. toList } else Seq.empty[String] + + private def wrap(font: FontRenderer, line: String, width: Int): java.util.List[String] = { + val list = new java.util.ArrayList[String] + font.getSplitter.splitLines(line, width, net.minecraft.util.text.Style.EMPTY, true, new ISliceAcceptor { + override def accept(style: Style, start: Int, end: Int) = list.add(line.substring(start, end)) + }) + list + } } diff --git a/src/main/scala/li/cil/oc/util/UpdateCheck.scala b/src/main/scala/li/cil/oc/util/UpdateCheck.scala index 25b0ccb8ec..e22206653d 100644 --- a/src/main/scala/li/cil/oc/util/UpdateCheck.scala +++ b/src/main/scala/li/cil/oc/util/UpdateCheck.scala @@ -7,8 +7,7 @@ import com.google.gson.Gson import com.google.gson.stream.JsonReader import li.cil.oc.OpenComputers import li.cil.oc.Settings -import net.minecraftforge.fml.common.Loader -import net.minecraftforge.fml.common.versioning.ComparableVersion +import org.apache.maven.artifact.versioning.ComparableVersion import scala.collection.mutable import scala.concurrent.ExecutionContext.Implicits.global @@ -23,7 +22,7 @@ object UpdateCheck { private def initialize(): Option[Release] = { // Keep the version template split up so it's not replaced with the actual version... - if (Settings.get.updateCheck && OpenComputers.Version != ("@" + "VERSION" + "@")) { + if (Settings.get.updateCheck && OpenComputers.get.Version != ("@" + "VERSION" + "@")) { try { OpenComputers.log.info("Starting OpenComputers version check.") val reader = new JsonReader(new InputStreamReader(releasesUrl.openStream())) @@ -39,7 +38,7 @@ object UpdateCheck { if (candidates.nonEmpty) { val latest = candidates.maxBy(release => new ComparableVersion(release.tag_name.stripPrefix("v"))) val remoteVersion = new ComparableVersion(latest.tag_name.stripPrefix("v")) - val localVersion = new ComparableVersion(Loader.instance.getIndexedModList.get(OpenComputers.ID).getVersion) + val localVersion = new ComparableVersion(OpenComputers.get.Version.toString) if (remoteVersion.compareTo(localVersion) > 0) { OpenComputers.log.info(s"A newer version of OpenComputers is available: ${latest.tag_name}.") return Some(latest) diff --git a/src/main/scala/li/cil/oc/util/UpgradeExperience.scala b/src/main/scala/li/cil/oc/util/UpgradeExperience.scala index afb6d530ef..6dc8ca6780 100644 --- a/src/main/scala/li/cil/oc/util/UpgradeExperience.scala +++ b/src/main/scala/li/cil/oc/util/UpgradeExperience.scala @@ -2,16 +2,16 @@ package li.cil.oc.util import li.cil.oc.Settings import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.CompoundNBT object UpgradeExperience { final val XpTag = Settings.namespace + "xp" - def getExperience(nbt: NBTTagCompound): Double = nbt.getDouble(XpTag) max 0 + def getExperience(nbt: CompoundNBT): Double = nbt.getDouble(XpTag) max 0 - def getExperience(stack: ItemStack): Double = if (!stack.hasTagCompound) 0 else getExperience(stack.getTagCompound) + def getExperience(stack: ItemStack): Double = if (!stack.hasTag) 0 else getExperience(stack.getTag) - def setExperience(nbt: NBTTagCompound, experience: Double): Unit = nbt.setDouble(XpTag, experience) + def setExperience(nbt: CompoundNBT, experience: Double): Unit = nbt.putDouble(XpTag, experience) def xpForLevel(level: Int): Double = if (level == 0) 0