Compare commits

..
13 Commits
Author SHA1 Message Date
Glease 8de7026a00 reformat project according to .editorconfig
Signed-off-by: Glease <4586901+Glease@users.noreply.github.com>
2022-07-08 17:14:18 +08:00
Glease 33d377cea7 pull in buildscript changes 2022-03-02 00:32:50 +08:00
Glease da98b476b0 fix off by one overflow 2022-03-01 23:56:04 +08:00
Martin Robertz 9dd145bc67 Merge pull request #4 from iouter/master
Update zh_CN.lang
2022-02-07 18:13:46 +01:00
iouter 83b7c35ed1 Update zh_CN.lang 2022-02-05 00:06:12 +08:00
Glease bb0bebf3a2 add debug log on multi passing check 2022-01-19 18:47:13 +08:00
Jason Mitchell a49ed1996b maven publish buildscript update 2022-01-17 23:58:46 -08:00
Martin Robertz 6d5d31f5ab Merge pull request #3 from GTNewHorizons/GTNH-Colen-patch-1
QoL fix for item description
2022-01-02 12:32:48 +01:00
GTNH-Colen 3eafe426ba QoL fix for item description
This item will now show in NEI when schematic is searched, in line with old TT schematic. The description is also more grammatically correct (removed extra caps).
2022-01-02 08:58:49 +00:00
Glease eea5227fe3 Pull my onlyIf from GT++ 2021-12-22 21:20:27 +08:00
Glease 1f520cfd73 Add localization stuff I forgot 2021-12-22 21:17:47 +08:00
Martin Robertz 8357fdc826 ignore bat files 2021-12-02 23:44:16 +01:00
Johann Bernhardt 27bb7b2ad9 Update build script and CI 2021-11-30 17:58:54 +08:00
47 changed files with 3162 additions and 2648 deletions

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
# This is the universal Text Editor Configuration
# for all GTNewHorizons projects
# See: https://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{bat,ini}]
end_of_line = crlf
[*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}]
indent_size = 2
-9
View File
@@ -1,9 +0,0 @@
directory="run/crash-reports"
if [ -d $directory ]; then
echo "Crash reports detected:"
cat $directory/*
exit 1
else
echo "No crash reports detected"
exit 0
fi
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# bashsupport disable=BP5006 # Global environment variables
RUNDIR="run" \
CRASH="crash-reports" \
SERVERLOG="server.log"
# enable nullglob to get 0 results when no match rather than the pattern
shopt -s nullglob
# store matches in array
crash_reports=("$RUNDIR/$CRASH/crash"*.txt)
# if array not empty there are crash_reports
if [ "${#crash_reports[@]}" -gt 0 ]; then
# get the latest crash_report from array
latest_crash_report="${crash_reports[-1]}"
{
printf 'Latest crash report detected %s:\n' "${latest_crash_report##*/}"
cat "$latest_crash_report"
} >&2
exit 1
fi
if grep --quiet --fixed-strings 'Fatal errors were detected' "$SERVERLOG"; then
{
printf 'Fatal errors detected:\n'
cat server.log
} >&2
exit 1
fi
if grep --quiet --fixed-strings 'The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED' \
"$SERVERLOG"; then
{
printf 'Server force stopped:'
cat server.log
} >&2
exit 1
fi
if ! grep --quiet --perl-regexp --only-matching '.+Done \(.+\)\! For help, type "help" or "\?"' "$SERVERLOG"; then
{
printf 'Server did not finish startup:'
cat server.log
} >&2
exit 1
fi
printf 'No crash reports detected'
exit 0
+10 -10
View File
@@ -14,32 +14,32 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up JDK 8 - name: Set up JDK 8
uses: actions/setup-java@v2 uses: actions/setup-java@v2
with: with:
java-version: '8' java-version: '8'
distribution: 'adopt' distribution: 'adopt'
cache: gradle cache: gradle
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew
- name: Setup the workspace - name: Setup the workspace
run: ./gradlew setupCIWorkspace run: ./gradlew setupCIWorkspace
- name: Build the mod - name: Build the mod
run: ./gradlew build run: ./gradlew build
- name: Run server for 1 minute - name: Run server for 1.5 minutes
run: | run: |
mkdir run mkdir run
echo "eula=true" > run/eula.txt echo "eula=true" > run/eula.txt
timeout 10 ./gradlew runServer || true timeout 90 ./gradlew runServer 2>&1 | tee -a server.log || true
- name: Test no crashes happend - name: Test no errors reported during server run
run: | run: |
chmod +x .github/scripts/test-no-crash-reports.sh chmod +x .github/scripts/test_no_error_reports
.github/scripts/test-no-crash-reports.sh .github/scripts/test_no_error_reports
-44
View File
@@ -1,44 +0,0 @@
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
name: Release latest build
on:
push:
branches: [ master, main ]
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set release version
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
distribution: 'adopt'
cache: gradle
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Setup the workspace
run: ./gradlew setupCIWorkspace
- name: Build the mod
run: ./gradlew build
- name: Update latest tag
uses: "marvinpinto/action-automatic-releases@latest"
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
prerelease: false
title: "Latest build"
files: build/libs/*.jar
+6
View File
@@ -43,3 +43,9 @@ jobs:
prerelease: false prerelease: false
title: "${{ env.RELEASE_VERSION }}" title: "${{ env.RELEASE_VERSION }}"
files: build/libs/*.jar files: build/libs/*.jar
- name: Publish to Maven
run: ./gradlew publish
env:
MAVEN_USER: ${{ secrets.MAVEN_USER }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
+1
View File
@@ -26,3 +26,4 @@ whitelist.json
*.ipr *.ipr
*.iws *.iws
src/main/resources/mixins.*.json src/main/resources/mixins.*.json
*.bat
+3
View File
@@ -0,0 +1,3 @@
# Any Github changes require admin approval
/.github/** @GTNewHorizons/admin
+356 -131
View File
@@ -1,49 +1,64 @@
//version: 4f3d1b46cf51f9d4ded5379b5d817a2a6f6b302d //version: 1644894948
/* /*
DO NOT CHANGE THIS FILE! DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available. Also, you may replace this file at any time if there is an update available.
Please check https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/build.gradle for updates. Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/ */
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
buildscript { buildscript {
repositories { repositories {
maven { maven {
name = "forge" name 'forge'
url = "https://maven.minecraftforge.net" url 'https://maven.minecraftforge.net'
} }
maven { maven {
name = "sonatype" name 'sonatype'
url = "https://oss.sonatype.org/content/repositories/snapshots/" url 'https://oss.sonatype.org/content/repositories/snapshots/'
} }
maven { maven {
name = "Scala CI dependencies" name 'Scala CI dependencies'
url = "https://repo1.maven.org/maven2/" url 'https://repo1.maven.org/maven2/'
} }
maven { maven {
name = "jitpack" name 'jitpack'
url = "https://jitpack.io" url 'https://jitpack.io'
} }
} }
dependencies { dependencies {
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.4' classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.7'
} }
} }
plugins { plugins {
id 'java-library'
id 'idea' id 'idea'
id 'eclipse'
id 'scala' id 'scala'
id("org.ajoberstar.grgit") version("3.1.1") id 'maven-publish'
id("com.github.johnrengelman.shadow") version("4.0.4") id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false
id("com.palantir.git-version") version("0.12.3") id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false
id 'org.ajoberstar.grgit' version '4.1.1'
id 'com.github.johnrengelman.shadow' version '4.0.4'
id 'com.palantir.git-version' version '0.13.0' apply false
id 'de.undercouch.download' version '5.0.1'
id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false
} }
if (project.file('.git/HEAD').isFile()) {
apply plugin: 'com.palantir.git-version'
}
def out = services.get(StyledTextOutputFactory).create('an-output')
apply plugin: 'forge' apply plugin: 'forge'
def projectJavaVersion = JavaLanguageVersion.of(8) def projectJavaVersion = JavaLanguageVersion.of(8)
@@ -62,6 +77,10 @@ idea {
} }
} }
if(JavaVersion.current() != JavaVersion.VERSION_1_8) {
throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current())
}
checkPropertyExists("modName") checkPropertyExists("modName")
checkPropertyExists("modId") checkPropertyExists("modId")
checkPropertyExists("modGroup") checkPropertyExists("modGroup")
@@ -83,33 +102,31 @@ checkPropertyExists("containsMixinsAndOrCoreModOnly")
checkPropertyExists("usesShadowedDependencies") checkPropertyExists("usesShadowedDependencies")
checkPropertyExists("developmentEnvironmentUserName") checkPropertyExists("developmentEnvironmentUserName")
def checkPropertyExists(String propertyName) { boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
if (project.hasProperty(propertyName) == false) {
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/gradle.properties")
}
}
String javaSourceDir = "src/main/java/" String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/" String scalaSourceDir = "src/main/scala/"
String kotlinSourceDir = "src/main/kotlin/"
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
if((new File(targetPackageJava).exists() || new File(targetPackageScala).exists()) == false) { String targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/")
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala) if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
} }
if(apiPackage) { if(apiPackage) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if((new File(targetPackageJava).exists() || new File(targetPackageScala).exists()) == false) { targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala) if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
} }
} }
if(accessTransformersFile) { if(accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if(new File(targetFile).exists() == false) { if(!getFile(targetFile).exists()) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile) throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
} }
} }
@@ -121,15 +138,17 @@ if(usesMixins.toBoolean()) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/") targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
if((new File(targetPackageJava).exists() || new File(targetPackageScala).exists()) == false) { targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala) if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
} }
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java" String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala" String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java" String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
if((new File(targetFileJava).exists() || new File(targetFileScala).exists() || new File(targetFileScalaJava).exists()) == false) { String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".kt"
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava) if(!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
} }
} }
@@ -137,8 +156,9 @@ if(coreModClass) {
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java" String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala" String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala"
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java" String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
if((new File(targetFileJava).exists() || new File(targetFileScala).exists() || new File(targetFileScalaJava).exists()) == false) { String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".kt"
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava) if(!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
} }
} }
@@ -151,15 +171,64 @@ configurations.all {
} }
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version // Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
'git config core.fileMode false'.execute() try {
// Pulls version from git tag 'git config core.fileMode false'.execute()
version = minecraftVersion + "-" + gitVersion() }
catch (Exception ignored) {
out.style(Style.Failure).println("git isn't installed at all")
}
// Pulls version first from the VERSION env and then git tag
String identifiedVersion
String versionOverride = System.getenv("VERSION") ?: null
try {
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
}
catch (Exception ignored) {
out.style(Style.Failure).text(
'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' +
'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' +
'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)'
)
versionOverride = 'NO-GIT-TAG-SET'
identifiedVersion = versionOverride
}
version = minecraftVersion + '-' + identifiedVersion
ext {
modVersion = identifiedVersion
}
if(identifiedVersion == versionOverride) {
out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7')
}
group = modGroup group = modGroup
archivesBaseName = modId if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
archivesBaseName = customArchiveBaseName
}
else {
archivesBaseName = modId
}
def arguments = []
def jvmArguments = []
if (usesMixins.toBoolean()) {
arguments += [
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
if (!project.hasProperty(usesMixinDebug) || usesMixinDebug.toBoolean()) {
jvmArguments += [
"-Dmixin.debug.countInjections=true",
"-Dmixin.debug.verbose=true",
"-Dmixin.debug.export=true"
]
}
}
minecraft { minecraft {
version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion version = minecraftVersion + '-' + forgeVersion + '-' + minecraftVersion
runDir = "run" runDir = 'run'
if (replaceGradleTokenInFile) { if (replaceGradleTokenInFile) {
replaceIn replaceGradleTokenInFile replaceIn replaceGradleTokenInFile
@@ -170,79 +239,99 @@ minecraft {
replace gradleTokenModName, modName replace gradleTokenModName, modName
} }
if(gradleTokenVersion) { if(gradleTokenVersion) {
replace gradleTokenVersion, versionDetails().lastTag replace gradleTokenVersion, modVersion
} }
if(gradleTokenGroupName) { if(gradleTokenGroupName) {
replace gradleTokenGroupName, modGroup replace gradleTokenGroupName, modGroup
} }
} }
clientIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
if(developmentEnvironmentUserName) {
args("--username", developmentEnvironmentUserName)
}
}
serverIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
}
} }
if(file("addon.gradle").exists()) { if(file('addon.gradle').exists()) {
apply from: "addon.gradle" apply from: 'addon.gradle'
} }
apply from: 'repositories.gradle' apply from: 'repositories.gradle'
configurations { configurations {
implementation.extendsFrom(shadowImplementation) implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored
implementation.extendsFrom(shadowCompile)
implementation.extendsFrom(shadeCompile)
} }
repositories { repositories {
maven { maven {
name = "Overmind forge repo mirror" name 'Overmind forge repo mirror'
url = "https://gregtech.overminddl1.com/" url 'https://gregtech.overminddl1.com/'
} }
if(usesMixins.toBoolean()) { if(usesMixins.toBoolean()) {
maven { maven {
name = "sponge" name 'sponge'
url = "https://repo.spongepowered.org/repository/maven-public" url 'https://repo.spongepowered.org/repository/maven-public'
} }
maven { maven {
url = "https://jitpack.io" url 'https://jitpack.io'
} }
} }
} }
dependencies { dependencies {
if(usesMixins.toBoolean()) { if(usesMixins.toBoolean()) {
annotationProcessor("org.ow2.asm:asm-debug-all:5.0.3") annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3')
annotationProcessor("com.google.guava:guava:24.1.1-jre") annotationProcessor('com.google.guava:guava:24.1.1-jre')
annotationProcessor("com.google.code.gson:gson:2.8.6") annotationProcessor('com.google.code.gson:gson:2.8.6')
annotationProcessor("org.spongepowered:mixin:0.8-SNAPSHOT") annotationProcessor('org.spongepowered:mixin:0.8-SNAPSHOT')
// using 0.8 to workaround a issue in 0.7 which fails mixin application // using 0.8 to workaround a issue in 0.7 which fails mixin application
compile("org.spongepowered:mixin:0.7.11-SNAPSHOT") { compile('com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH') {
// Mixin includes a lot of dependencies that are too up-to-date // Mixin includes a lot of dependencies that are too up-to-date
exclude module: "launchwrapper" exclude module: 'launchwrapper'
exclude module: "guava" exclude module: 'guava'
exclude module: "gson" exclude module: 'gson'
exclude module: "commons-io" exclude module: 'commons-io'
exclude module: "log4j-core" exclude module: 'log4j-core'
} }
compile("com.github.GTNewHorizons:SpongeMixins:1.3.3:dev") compile('com.github.GTNewHorizons:SpongeMixins:1.5.0')
} }
} }
apply from: 'dependencies.gradle' apply from: 'dependencies.gradle'
def mixinConfigJson = "mixins." + modId + ".json" def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
def mixingConfigRefMap = "mixins." + modId + ".refmap.json"
def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap
def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg" def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg"
task generateAssets { task generateAssets {
if(usesMixins.toBoolean()) { if (usesMixins.toBoolean()) {
new File(projectDir.toString() + "/src/main/resources/", mixinConfigJson).text = """{ def mixinConfigFile = getFile("/src/main/resources/mixins." + modId + ".json");
if (!mixinConfigFile.exists()) {
mixinConfigFile.text = """{
"required": true, "required": true,
"minVersion": "0.7.11", "minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}", "package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}", "plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}", "refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)", "target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8" "compatibilityLevel": "JAVA_8",
"mixins": [],
"client": [],
"server": []
} }
""" """
}
} }
} }
@@ -252,16 +341,28 @@ task relocateShadowJar(type: ConfigureShadowRelocation) {
} }
shadowJar { shadowJar {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
manifest { manifest {
attributes(getManifestAttributes()) attributes(getManifestAttributes())
} }
minimize() // This will only allow shading for actually used classes minimize() // This will only allow shading for actually used classes
configurations = [project.configurations.shadowImplementation] configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile]
dependsOn(relocateShadowJar) dependsOn(relocateShadowJar)
} }
jar { jar {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
manifest { manifest {
attributes(getManifestAttributes()) attributes(getManifestAttributes())
} }
@@ -294,15 +395,6 @@ afterEvaluate {
} }
runClient { runClient {
def arguments = []
if(usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
if(developmentEnvironmentUserName) { if(developmentEnvironmentUserName) {
arguments += [ arguments += [
"--username", "--username",
@@ -311,19 +403,12 @@ runClient {
} }
args(arguments) args(arguments)
jvmArgs(jvmArguments)
} }
runServer { runServer {
def arguments = []
if (usesMixins.toBoolean()) {
arguments += [
"--mods=../build/libs/$modId-${version}.jar",
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
}
args(arguments) args(arguments)
jvmArgs(jvmArguments)
} }
tasks.withType(JavaExec).configureEach { tasks.withType(JavaExec).configureEach {
@@ -334,32 +419,35 @@ tasks.withType(JavaExec).configureEach {
) )
} }
processResources processResources {
{ // this will ensure that this task is redone when the versions change.
// this will ensure that this task is redone when the versions change. inputs.property "version", project.version
inputs.property "version", project.version inputs.property "mcversion", project.minecraft.version
inputs.property "mcversion", project.minecraft.version
// replace stuff in mcmod.info, nothing else // replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info' include 'mcmod.info'
// replace version and mcversion // replace modVersion and minecraftVersion
expand "minecraftVersion": project.minecraft.version, expand "minecraftVersion": project.minecraft.version,
"modVersion": versionDetails().lastTag, "modVersion": modVersion,
"modId": modId, "modId": modId,
"modName": modName "modName": modName
} }
// copy everything else, thats not the mcmod.info if(usesMixins.toBoolean()) {
from(sourceSets.main.resources.srcDirs) { from refMap
exclude 'mcmod.info' }
}
} // copy everything else that's not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
def getManifestAttributes() { def getManifestAttributes() {
def manifestAttributes = [:] def manifestAttributes = [:]
if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) { if(!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) {
manifestAttributes += ["FMLCorePluginContainsFMLMod": true] manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
} }
@@ -374,20 +462,26 @@ def getManifestAttributes() {
if(usesMixins.toBoolean()) { if(usesMixins.toBoolean()) {
manifestAttributes += [ manifestAttributes += [
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker", "TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
"MixinConfigs" : mixinConfigJson, "MixinConfigs" : "mixins." + modId + ".json",
"ForceLoadAsMod" : containsMixinsAndOrCoreModOnly.toBoolean() == false "ForceLoadAsMod" : !containsMixinsAndOrCoreModOnly.toBoolean()
] ]
} }
return manifestAttributes return manifestAttributes
} }
task sourcesJar(type: Jar) { task sourcesJar(type: Jar) {
from (sourceSets.main.allJava) from (sourceSets.main.allSource)
from (file("$projectDir/LICENSE")) from (file("$projectDir/LICENSE"))
getArchiveClassifier().set('sources') getArchiveClassifier().set('sources')
} }
task shadowDevJar(type: ShadowJar) { task shadowDevJar(type: ShadowJar) {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
from sourceSets.main.output from sourceSets.main.output
getArchiveClassifier().set("dev") getArchiveClassifier().set("dev")
@@ -396,7 +490,7 @@ task shadowDevJar(type: ShadowJar) {
} }
minimize() // This will only allow shading for actually used classes minimize() // This will only allow shading for actually used classes
configurations = [project.configurations.shadowImplementation] configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile]
} }
task relocateShadowDevJar(type: ConfigureShadowRelocation) { task relocateShadowDevJar(type: ConfigureShadowRelocation) {
@@ -411,6 +505,12 @@ task circularResolverJar(type: Jar) {
} }
task devJar(type: Jar) { task devJar(type: Jar) {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
from sourceSets.main.output from sourceSets.main.output
getArchiveClassifier().set("dev") getArchiveClassifier().set("dev")
@@ -425,12 +525,12 @@ task devJar(type: Jar) {
} }
task apiJar(type: Jar) { task apiJar(type: Jar) {
from (sourceSets.main.allJava) { from (sourceSets.main.allSource) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString() + '/**' include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
} }
from (sourceSets.main.output) { from (sourceSets.main.output) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString() + '/**' include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
} }
from (sourceSets.main.resources.srcDirs) { from (sourceSets.main.resources.srcDirs) {
@@ -441,24 +541,71 @@ task apiJar(type: Jar) {
} }
artifacts { artifacts {
archives sourcesJar if(!noPublishedSources) {
archives sourcesJar
}
archives devJar archives devJar
if(apiPackage) { if(apiPackage) {
archives apiJar archives apiJar
} }
} }
// Crude handler to append custom maven repositories to maven dependency // The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID),
install{ // and isn't strictly needed with the POM so just disable it.
repositories{ tasks.withType(GenerateModuleMetadata) {
mavenInstaller{ enabled = false
}
// workaround variable hiding in pom processing
def projectConfigs = project.configurations
publishing {
publications {
maven(MavenPublication) {
from components.java
if(usesShadowedDependencies.toBoolean()) {
artifact source: shadowJar, classifier: ""
}
if(!noPublishedSources) {
artifact source: sourcesJar, classifier: "src"
}
artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev"
if (apiPackage) {
artifact source: apiJar, classifier: "api"
}
groupId = System.getenv("ARTIFACT_GROUP_ID") ?: "com.github.GTNewHorizons"
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
// Using the identified version, not project.version as it has the prepended 1.7.10
version = System.getenv("RELEASE_VERSION") ?: identifiedVersion
// remove extra garbage from minecraft and minecraftDeps configuration
pom.withXml { pom.withXml {
def repositoriesNode = asNode().appendNode("repositories") def badArtifacts = [:].withDefault {[] as Set<String>}
project.repositories.each { repository -> for (configuration in [projectConfigs.minecraft, projectConfigs.minecraftDeps]) {
def repositoryNode = repositoriesNode.appendNode("repository") for (dependency in configuration.allDependencies) {
repositoryNode.appendNode("name", repository.name) badArtifacts[dependency.group == null ? "" : dependency.group] += dependency.name
repositoryNode.appendNode("url", repository.properties.get("url")) }
} }
// example for specifying extra stuff to ignore
// badArtifacts["org.example.group"] += "artifactName"
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
badArtifacts[it.groupId.text()].contains(it.artifactId.text())
}.each() {
it.parent().remove(it)
}
}
}
}
repositories {
maven {
url = "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases"
credentials {
username = System.getenv("MAVEN_USER") ?: "NONE"
password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
} }
} }
} }
@@ -467,38 +614,38 @@ install{
// Updating // Updating
task updateBuildScript { task updateBuildScript {
doLast { doLast {
if (updateBuildScript()) return if (performBuildScriptUpdate(projectDir.toString())) return
print("Build script already up-to-date!") print("Build script already up-to-date!")
} }
} }
if (isNewBuildScriptVersionAvailable()) { if (isNewBuildScriptVersionAvailable(projectDir.toString())) {
if (autoUpdateBuildScript.toBoolean()) { if (autoUpdateBuildScript.toBoolean()) {
updateBuildScript() performBuildScriptUpdate(projectDir.toString())
} else { } else {
println("Build script update available! Run 'gradle updateBuildScript'") out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
} }
} }
static URL availableBuildScriptUrl() { static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/SinTh0r4s/ExampleMod1.7.10/main/build.gradle") new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/main/build.gradle")
} }
static boolean updateBuildScript() { boolean performBuildScriptUpdate(String projectDir) {
if (isNewBuildScriptVersionAvailable()) { if (isNewBuildScriptVersionAvailable(projectDir)) {
def buildscriptFile = new File("build.gradle") def buildscriptFile = getFile("build.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } } availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
print("Build script updated. Please REIMPORT the project or RESTART your IDE!") out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
return true return true
} }
return false return false
} }
static boolean isNewBuildScriptVersionAvailable() { boolean isNewBuildScriptVersionAvailable(String projectDir) {
Map parameters = ["connectTimeout": 2000, "readTimeout": 2000] Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
String currentBuildScript = new File("build.gradle").getText() String currentBuildScript = getFile("build.gradle").getText()
String currentBuildScriptHash = getVersionHash(currentBuildScript) String currentBuildScriptHash = getVersionHash(currentBuildScript)
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText() String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
String availableBuildScriptHash = getVersionHash(availableBuildScript) String availableBuildScriptHash = getVersionHash(availableBuildScript)
@@ -519,3 +666,81 @@ configure(updateBuildScript) {
group = 'forgegradle' group = 'forgegradle'
description = 'Updates the build script to the latest version' description = 'Updates the build script to the latest version'
} }
// Deobfuscation
def deobf(String sourceURL) {
try {
URL url = new URL(sourceURL)
String fileName = url.getFile()
//get rid of directories:
int lastSlash = fileName.lastIndexOf("/")
if(lastSlash > 0) {
fileName = fileName.substring(lastSlash + 1)
}
//get rid of extension:
if(fileName.endsWith(".jar")) {
fileName = fileName.substring(0, fileName.lastIndexOf("."))
}
String hostName = url.getHost()
if(hostName.startsWith("www.")) {
hostName = hostName.substring(4)
}
List parts = Arrays.asList(hostName.split("\\."))
Collections.reverse(parts)
hostName = String.join(".", parts)
return deobf(sourceURL, hostName + "/" + fileName)
} catch(Exception e) {
return deobf(sourceURL, "deobf/" + String.valueOf(sourceURL.hashCode()))
}
}
// The method above is to be preferred. Use this method if the filename is not at the end of the URL.
def deobf(String sourceURL, String fileName) {
String cacheDir = System.getProperty("user.home") + "/.gradle/caches/"
String bon2Dir = cacheDir + "forge_gradle/deobf"
String bon2File = bon2Dir + "/BON2-2.5.0.jar"
String obfFile = cacheDir + "modules-2/files-2.1/" + fileName + ".jar"
String deobfFile = cacheDir + "modules-2/files-2.1/" + fileName + "-deobf.jar"
if(file(deobfFile).exists()) {
return files(deobfFile)
}
download.run {
src 'https://github.com/GTNewHorizons/BON2/releases/download/2.5.0/BON2-2.5.0.CUSTOM-all.jar'
dest bon2File
quiet true
overwrite false
}
download.run {
src sourceURL
dest obfFile
quiet true
overwrite false
}
exec {
commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', '1.7.10', '--mappingsVer', 'stable_12', '--notch'
workingDir bon2Dir
standardOutput = new ByteArrayOutputStream()
}
return files(deobfFile)
}
// Helper methods
def checkPropertyExists(String propertyName) {
if (!project.hasProperty(propertyName)) {
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties")
}
}
def getFile(String relativePath) {
return new File(projectDir, relativePath)
}
@@ -18,8 +18,8 @@ public class GuiModConfig extends GuiConfig {
private static List<IConfigElement> getConfigElements() { private static List<IConfigElement> getConfigElements() {
final Configuration config = ConfigurationHandler.INSTANCE.getConfig(); final Configuration config = ConfigurationHandler.INSTANCE.getConfig();
return config.getCategoryNames().stream() return config.getCategoryNames().stream()
.filter(name -> name.indexOf('.') == -1) .filter(name -> name.indexOf('.') == -1)
.map(name -> new ConfigElement(config.getCategory(name))) .map(name -> new ConfigElement(config.getCategory(name)))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
} }
@@ -28,51 +28,51 @@ import org.apache.logging.log4j.Logger;
*/ */
@Mod(modid = StructureLibAPI.MOD_ID, name = "StructureLib", version = "GRADLETOKEN_VERSION", acceptableRemoteVersions = "*", guiFactory = "com.gtnewhorizon.structurelib.GuiFactory") @Mod(modid = StructureLibAPI.MOD_ID, name = "StructureLib", version = "GRADLETOKEN_VERSION", acceptableRemoteVersions = "*", guiFactory = "com.gtnewhorizon.structurelib.GuiFactory")
public class StructureLib { public class StructureLib {
public static boolean DEBUG_MODE = Boolean.getBoolean("structurelib.debug"); public static boolean DEBUG_MODE = Boolean.getBoolean("structurelib.debug");
public static Logger LOGGER = LogManager.getLogger("StructureLib"); public static Logger LOGGER = LogManager.getLogger("StructureLib");
@SidedProxy(serverSide = "com.gtnewhorizon.structurelib.proxy.CommonProxy", clientSide = "com.gtnewhorizon.structurelib.proxy.ClientProxy") @SidedProxy(serverSide = "com.gtnewhorizon.structurelib.proxy.CommonProxy", clientSide = "com.gtnewhorizon.structurelib.proxy.ClientProxy")
static CommonProxy proxy; static CommonProxy proxy;
static SimpleNetworkWrapper net = NetworkRegistry.INSTANCE.newSimpleChannel(StructureLibAPI.MOD_ID); static SimpleNetworkWrapper net = NetworkRegistry.INSTANCE.newSimpleChannel(StructureLibAPI.MOD_ID);
static { static {
net.registerMessage(AlignmentMessage.ServerHandler.class, AlignmentMessage.AlignmentQuery.class, 0, Side.SERVER); net.registerMessage(AlignmentMessage.ServerHandler.class, AlignmentMessage.AlignmentQuery.class, 0, Side.SERVER);
net.registerMessage(AlignmentMessage.ClientHandler.class, AlignmentMessage.AlignmentData.class, 1, Side.CLIENT); net.registerMessage(AlignmentMessage.ClientHandler.class, AlignmentMessage.AlignmentData.class, 1, Side.CLIENT);
} }
public static final XSTR RANDOM = new XSTR(); public static final XSTR RANDOM = new XSTR();
static Block blockHint; static Block blockHint;
static Item itemBlockHint; static Item itemBlockHint;
static Item itemFrontRotationTool; static Item itemFrontRotationTool;
static Item itemConstructableTrigger; static Item itemConstructableTrigger;
public static final CreativeTabs creativeTab = new CreativeTabs("structurelib") { public static final CreativeTabs creativeTab = new CreativeTabs("structurelib") {
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public Item getTabIconItem() { public Item getTabIconItem() {
return StructureLibAPI.getItemBlockHint(); return StructureLibAPI.getItemBlockHint();
} }
}; };
@Mod.EventHandler @Mod.EventHandler
public void preInit(FMLPreInitializationEvent e) { public void preInit(FMLPreInitializationEvent e) {
ConfigurationHandler.INSTANCE.init(e.getSuggestedConfigurationFile()); ConfigurationHandler.INSTANCE.init(e.getSuggestedConfigurationFile());
GameRegistry.registerBlock(blockHint = new BlockHint(), ItemBlockHint.class, "blockhint"); GameRegistry.registerBlock(blockHint = new BlockHint(), ItemBlockHint.class, "blockhint");
itemBlockHint = ItemBlock.getItemFromBlock(StructureLibAPI.getBlockHint()); itemBlockHint = ItemBlock.getItemFromBlock(StructureLibAPI.getBlockHint());
GameRegistry.registerItem(itemFrontRotationTool = new ItemFrontRotationTool(), itemFrontRotationTool.getUnlocalizedName()); GameRegistry.registerItem(itemFrontRotationTool = new ItemFrontRotationTool(), itemFrontRotationTool.getUnlocalizedName());
GameRegistry.registerItem(itemConstructableTrigger = new ItemConstructableTrigger(), itemConstructableTrigger.getUnlocalizedName()); GameRegistry.registerItem(itemConstructableTrigger = new ItemConstructableTrigger(), itemConstructableTrigger.getUnlocalizedName());
proxy.preInit(e); proxy.preInit(e);
} }
public static void addClientSideChatMessages(String... messages) { public static void addClientSideChatMessages(String... messages) {
proxy.addClientSideChatMessages(messages); proxy.addClientSideChatMessages(messages);
} }
public static EntityPlayer getCurrentPlayer() { public static EntityPlayer getCurrentPlayer() {
return proxy.getCurrentPlayer(); return proxy.getCurrentPlayer();
} }
public static boolean isCurrentPlayer(EntityPlayer player) { public static boolean isCurrentPlayer(EntityPlayer player) {
return proxy.isCurrentPlayer(player); return proxy.isCurrentPlayer(player);
} }
} }
@@ -18,114 +18,119 @@ import static com.gtnewhorizon.structurelib.StructureLib.proxy;
* A stable interface into the structure lib's internals. Backwards compatibility is maintained to the maximum extend possible. * A stable interface into the structure lib's internals. Backwards compatibility is maintained to the maximum extend possible.
*/ */
public class StructureLibAPI { public class StructureLibAPI {
public static final String MOD_ID = "structurelib"; public static final String MOD_ID = "structurelib";
public static final int HINT_BLOCK_META_GENERIC_0 = 0; public static final int HINT_BLOCK_META_GENERIC_0 = 0;
public static final int HINT_BLOCK_META_GENERIC_1 = 1; public static final int HINT_BLOCK_META_GENERIC_1 = 1;
public static final int HINT_BLOCK_META_GENERIC_2 = 2; public static final int HINT_BLOCK_META_GENERIC_2 = 2;
public static final int HINT_BLOCK_META_GENERIC_3 = 3; public static final int HINT_BLOCK_META_GENERIC_3 = 3;
public static final int HINT_BLOCK_META_GENERIC_4 = 4; public static final int HINT_BLOCK_META_GENERIC_4 = 4;
public static final int HINT_BLOCK_META_GENERIC_5 = 5; public static final int HINT_BLOCK_META_GENERIC_5 = 5;
public static final int HINT_BLOCK_META_GENERIC_6 = 6; public static final int HINT_BLOCK_META_GENERIC_6 = 6;
public static final int HINT_BLOCK_META_GENERIC_7 = 7; public static final int HINT_BLOCK_META_GENERIC_7 = 7;
public static final int HINT_BLOCK_META_GENERIC_8 = 8; public static final int HINT_BLOCK_META_GENERIC_8 = 8;
public static final int HINT_BLOCK_META_GENERIC_9 = 9; public static final int HINT_BLOCK_META_GENERIC_9 = 9;
public static final int HINT_BLOCK_META_GENERIC_10 = 10; public static final int HINT_BLOCK_META_GENERIC_10 = 10;
public static final int HINT_BLOCK_META_GENERIC_11 = 11; public static final int HINT_BLOCK_META_GENERIC_11 = 11;
public static final int HINT_BLOCK_META_DEFAULT = 12; public static final int HINT_BLOCK_META_DEFAULT = 12;
public static final int HINT_BLOCK_META_AIR = 13; public static final int HINT_BLOCK_META_AIR = 13;
public static final int HINT_BLOCK_META_NOT_AIR = 14; public static final int HINT_BLOCK_META_NOT_AIR = 14;
public static final int HINT_BLOCK_META_ERROR = 15; public static final int HINT_BLOCK_META_ERROR = 15;
/** /**
* Start a batch of hinting. All hints particles generated during one batch will be considered to belong to one hologram. * Start a batch of hinting. All hints particles generated during one batch will be considered to belong to one hologram.
* * <p>
* You don't need to call this unless your constructable tool didn't call {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)} * You don't need to call this unless your constructable tool didn't call {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)}
*/ */
public static void startHinting(World w) { public static void startHinting(World w) {
proxy.startHinting(w); proxy.startHinting(w);
} }
/** /**
* Start current batch of hinting. All hints particles generated during one batch will be considered to belong to one hologram. * Start current batch of hinting. All hints particles generated during one batch will be considered to belong to one hologram.
* * <p>
* You don't need to call this unless your constructable tool didn't call {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)} * You don't need to call this unless your constructable tool didn't call {@link com.gtnewhorizon.structurelib.alignment.constructable.ConstructableUtility#handle(ItemStack, EntityPlayer, World, int, int, int, int)}
*/ */
public static void endHinting(World w) { public static void endHinting(World w) {
proxy.endHinting(w); proxy.endHinting(w);
} }
public static void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) { public static void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) {
proxy.hintParticleTinted(w, x, y, z, icons, RGBa); proxy.hintParticleTinted(w, x, y, z, icons, RGBa);
} }
public static void hintParticleTinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa) { public static void hintParticleTinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa) {
proxy.hintParticleTinted(w, x, y, z, block, meta, RGBa); proxy.hintParticleTinted(w, x, y, z, block, meta, RGBa);
} }
public static void hintParticle(World w, int x, int y, int z, IIcon[] icons) { public static void hintParticle(World w, int x, int y, int z, IIcon[] icons) {
proxy.hintParticle(w, x, y, z, icons); proxy.hintParticle(w, x, y, z, icons);
} }
public static void hintParticle(World w, int x, int y, int z, Block block, int meta) { public static void hintParticle(World w, int x, int y, int z, Block block, int meta) {
proxy.hintParticle(w, x, y, z, block, meta); proxy.hintParticle(w, x, y, z, block, meta);
} }
/** /**
* Query the ExtendedFacing of this tile entity. * Query the ExtendedFacing of this tile entity.
* The ExtendedFacing will later be set onto given tile entity via {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)} * The ExtendedFacing will later be set onto given tile entity via {@link com.gtnewhorizon.structurelib.alignment.IAlignment#setExtendedFacing(ExtendedFacing)}
* upon arrival of server reply. * upon arrival of server reply.
* @throws IllegalArgumentException if is not tile entity or provided a null alignment *
*/ * @throws IllegalArgumentException if is not tile entity or provided a null alignment
public static void queryAlignment(IAlignmentProvider provider) { */
StructureLib.net.sendToServer(new AlignmentMessage.AlignmentQuery(provider)); public static void queryAlignment(IAlignmentProvider provider) {
} StructureLib.net.sendToServer(new AlignmentMessage.AlignmentQuery(provider));
}
/** /**
* Send the ExtendedFacing of this Tile Entity to all players. Can be called on server side only. * Send the ExtendedFacing of this Tile Entity to all players. Can be called on server side only.
* @throws IllegalArgumentException if is not tile entity or provided a null alignment *
*/ * @throws IllegalArgumentException if is not tile entity or provided a null alignment
public static void sendAlignment(IAlignmentProvider provider) { */
StructureLib.net.sendToAll(new AlignmentMessage.AlignmentData(provider)); public static void sendAlignment(IAlignmentProvider provider) {
} StructureLib.net.sendToAll(new AlignmentMessage.AlignmentData(provider));
}
/** /**
* Send the ExtendedFacing of this Tile Entity to given player. Can be called on server side only. * Send the ExtendedFacing of this Tile Entity to given player. Can be called on server side only.
* @throws IllegalArgumentException if is not tile entity or provided a null alignment *
*/ * @throws IllegalArgumentException if is not tile entity or provided a null alignment
public static void sendAlignment(IAlignmentProvider provider, EntityPlayerMP player) { */
StructureLib.net.sendTo(new AlignmentMessage.AlignmentData(provider), player); public static void sendAlignment(IAlignmentProvider provider, EntityPlayerMP player) {
} StructureLib.net.sendTo(new AlignmentMessage.AlignmentData(provider), player);
}
/** /**
* Send the ExtendedFacing of this Tile Entity to all players around target point. Can be called on server side only. * Send the ExtendedFacing of this Tile Entity to all players around target point. Can be called on server side only.
* @throws IllegalArgumentException if is not tile entity or provided a null alignment *
*/ * @throws IllegalArgumentException if is not tile entity or provided a null alignment
public static void sendAlignment(IAlignmentProvider provider, NetworkRegistry.TargetPoint targetPoint) { */
StructureLib.net.sendToAllAround(new AlignmentMessage.AlignmentData(provider), targetPoint); public static void sendAlignment(IAlignmentProvider provider, NetworkRegistry.TargetPoint targetPoint) {
} StructureLib.net.sendToAllAround(new AlignmentMessage.AlignmentData(provider), targetPoint);
}
/** /**
* Send the ExtendedFacing of this Tile Entity to all players in that dimension. Can be called on server side only. * Send the ExtendedFacing of this Tile Entity to all players in that dimension. Can be called on server side only.
* @throws IllegalArgumentException if is not tile entity or provided a null alignment *
*/ * @throws IllegalArgumentException if is not tile entity or provided a null alignment
public static void sendAlignment(IAlignmentProvider provider, World dimension) { */
StructureLib.net.sendToDimension(new AlignmentMessage.AlignmentData(provider), dimension.provider.dimensionId); public static void sendAlignment(IAlignmentProvider provider, World dimension) {
} StructureLib.net.sendToDimension(new AlignmentMessage.AlignmentData(provider), dimension.provider.dimensionId);
}
public static Block getBlockHint() { public static Block getBlockHint() {
return StructureLib.blockHint; return StructureLib.blockHint;
} }
public static Item getItemBlockHint() { public static Item getItemBlockHint() {
return StructureLib.itemBlockHint; return StructureLib.itemBlockHint;
} }
public static boolean isDebugEnabled() { public static boolean isDebugEnabled() {
return StructureLib.DEBUG_MODE; return StructureLib.DEBUG_MODE;
} }
public static void setDebugEnabled(boolean enabled) { public static void setDebugEnabled(boolean enabled) {
StructureLib.DEBUG_MODE = enabled; StructureLib.DEBUG_MODE = enabled;
} }
} }
@@ -7,10 +7,10 @@ import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.FakePlayer;
public class AlignmentUtility { public class AlignmentUtility {
private AlignmentUtility(){ private AlignmentUtility() {
} }
public static boolean handle(EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ){ public static boolean handle(EntityPlayer aPlayer, World aWorld, int aX, int aY, int aZ) {
TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ); TileEntity tTileEntity = aWorld.getTileEntity(aX, aY, aZ);
if (tTileEntity == null || aPlayer instanceof FakePlayer) { if (tTileEntity == null || aPlayer instanceof FakePlayer) {
return aPlayer instanceof EntityPlayerMP; return aPlayer instanceof EntityPlayerMP;
@@ -6,61 +6,65 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
public interface IAlignment extends IAlignmentLimits,IAlignmentProvider { public interface IAlignment extends IAlignmentLimits, IAlignmentProvider {
int DIRECTIONS_COUNT= Direction.VALUES.length; int DIRECTIONS_COUNT = Direction.VALUES.length;
int ROTATIONS_COUNT= Rotation.VALUES.length; int ROTATIONS_COUNT = Rotation.VALUES.length;
int FLIPS_COUNT= Flip.VALUES.length; int FLIPS_COUNT = Flip.VALUES.length;
int STATES_COUNT = ExtendedFacing.STATES_COUNT; int STATES_COUNT = ExtendedFacing.STATES_COUNT;
ExtendedFacing getExtendedFacing(); ExtendedFacing getExtendedFacing();
/**
* Set the facing without additional checks.
* Tools altering facing should use {@link #toolSetExtendedFacing(ExtendedFacing)} instead.
*/
void setExtendedFacing(ExtendedFacing alignment); void setExtendedFacing(ExtendedFacing alignment);
IAlignmentLimits getAlignmentLimits(); IAlignmentLimits getAlignmentLimits();
@Override @Override
default IAlignment getAlignment(){ default IAlignment getAlignment() {
return this; return this;
} }
static int getAlignmentIndex(ForgeDirection direction, Rotation rotation, Flip flip){ static int getAlignmentIndex(ForgeDirection direction, Rotation rotation, Flip flip) {
return (direction.ordinal()*ROTATIONS_COUNT+rotation.getIndex())*FLIPS_COUNT+flip.getIndex(); return (direction.ordinal() * ROTATIONS_COUNT + rotation.getIndex()) * FLIPS_COUNT + flip.getIndex();
} }
default ForgeDirection getDirection(){ default ForgeDirection getDirection() {
return getExtendedFacing().getDirection(); return getExtendedFacing().getDirection();
} }
default void setDirection(ForgeDirection direction){ default void setDirection(ForgeDirection direction) {
setExtendedFacing(getExtendedFacing().with(direction)); setExtendedFacing(getExtendedFacing().with(direction));
} }
default Rotation getRotation(){ default Rotation getRotation() {
return getExtendedFacing().getRotation(); return getExtendedFacing().getRotation();
} }
default void setRotation(Rotation rotation){ default void setRotation(Rotation rotation) {
setExtendedFacing(getExtendedFacing().with(rotation)); setExtendedFacing(getExtendedFacing().with(rotation));
} }
default Flip getFlip(){ default Flip getFlip() {
return getExtendedFacing().getFlip(); return getExtendedFacing().getFlip();
} }
default void setFlip(Flip flip){ default void setFlip(Flip flip) {
setExtendedFacing(getExtendedFacing().with(flip)); setExtendedFacing(getExtendedFacing().with(flip));
} }
default boolean toolSetDirection(ForgeDirection direction){ default boolean toolSetDirection(ForgeDirection direction) {
if(direction==null || direction==ForgeDirection.UNKNOWN){ if (direction == null || direction == ForgeDirection.UNKNOWN) {
for (int i = 0,j=getDirection().ordinal()+1, valuesLength = Direction.VALUES.length; i < valuesLength; i++) { for (int i = 0, j = getDirection().ordinal() + 1, valuesLength = Direction.VALUES.length; i < valuesLength; i++) {
if (toolSetDirection(Direction.VALUES[(j + i) % valuesLength].getForgeDirection())) { if (toolSetDirection(Direction.VALUES[(j + i) % valuesLength].getForgeDirection())) {
return true; return true;
} }
} }
}else { } else {
for (ExtendedFacing extendedFacing : ExtendedFacing.FOR_FACING.get(direction)) { for (ExtendedFacing extendedFacing : ExtendedFacing.FOR_FACING.get(direction)) {
if(checkedSetExtendedFacing(extendedFacing)){ if (checkedSetExtendedFacing(extendedFacing)) {
return true; return true;
} }
} }
@@ -68,17 +72,17 @@ public interface IAlignment extends IAlignmentLimits,IAlignmentProvider {
return false; return false;
} }
default boolean checkedSetDirection(ForgeDirection direction){ default boolean checkedSetDirection(ForgeDirection direction) {
if (isNewDirectionValid(direction)){ if (isNewDirectionValid(direction)) {
setDirection(direction); setDirection(direction);
return true; return true;
} }
return false; return false;
} }
default boolean canSetToDirectionAny(ForgeDirection direction){ default boolean canSetToDirectionAny(ForgeDirection direction) {
for (ExtendedFacing extendedFacing : ExtendedFacing.FOR_FACING.get(direction)) { for (ExtendedFacing extendedFacing : ExtendedFacing.FOR_FACING.get(direction)) {
if(isNewExtendedFacingValid(extendedFacing)){ if (isNewExtendedFacingValid(extendedFacing)) {
return true; return true;
} }
} }
@@ -86,10 +90,10 @@ public interface IAlignment extends IAlignmentLimits,IAlignmentProvider {
} }
default boolean toolSetRotation(Rotation rotation) { default boolean toolSetRotation(Rotation rotation) {
if(rotation==null){ if (rotation == null) {
int flips = Flip.VALUES.length; int flips = Flip.VALUES.length;
int rotations = Rotation.VALUES.length; int rotations = Rotation.VALUES.length;
for (int ii = 0,jj=getFlip().ordinal(); ii < flips; ii++) { for (int ii = 0, jj = getFlip().ordinal(); ii < flips; ii++) {
for (int i = 1, j = getRotation().ordinal(); i < rotations; i++) { for (int i = 1, j = getRotation().ordinal(); i < rotations; i++) {
if (checkedSetExtendedFacing(ExtendedFacing.of(getDirection(), Rotation.VALUES[(j + i) % rotations], Flip.VALUES[(jj + ii) % flips]))) { if (checkedSetExtendedFacing(ExtendedFacing.of(getDirection(), Rotation.VALUES[(j + i) % rotations], Flip.VALUES[(jj + ii) % flips]))) {
return true; return true;
@@ -97,55 +101,55 @@ public interface IAlignment extends IAlignmentLimits,IAlignmentProvider {
} }
} }
return false; return false;
}else { } else {
return checkedSetRotation(rotation); return checkedSetRotation(rotation);
} }
} }
default boolean checkedSetRotation(Rotation rotation){ default boolean checkedSetRotation(Rotation rotation) {
if (isNewRotationValid(rotation)){ if (isNewRotationValid(rotation)) {
setRotation(rotation); setRotation(rotation);
return true; return true;
} }
return false; return false;
} }
default boolean toolSetFlip(Flip flip){ default boolean toolSetFlip(Flip flip) {
if(flip==null){ if (flip == null) {
for (int i = 1, j = getFlip().ordinal(), valuesLength = Flip.VALUES.length; i < valuesLength; i++) { for (int i = 1, j = getFlip().ordinal(), valuesLength = Flip.VALUES.length; i < valuesLength; i++) {
if (checkedSetFlip(Flip.VALUES[(j + i) % valuesLength])) { if (checkedSetFlip(Flip.VALUES[(j + i) % valuesLength])) {
return true; return true;
} }
} }
return false; return false;
}else { } else {
return checkedSetFlip(flip); return checkedSetFlip(flip);
} }
} }
default boolean checkedSetFlip(Flip flip){ default boolean checkedSetFlip(Flip flip) {
if (isNewFlipValid(flip)){ if (isNewFlipValid(flip)) {
setFlip(flip); setFlip(flip);
return true; return true;
} }
return false; return false;
} }
default boolean toolSetExtendedFacing(ExtendedFacing extendedFacing){ default boolean toolSetExtendedFacing(ExtendedFacing extendedFacing) {
if(extendedFacing==null){ if (extendedFacing == null) {
for (int i = 0,j=getExtendedFacing().ordinal()+1, valuesLength = ExtendedFacing.VALUES.length; i < valuesLength; i++) { for (int i = 0, j = getExtendedFacing().ordinal() + 1, valuesLength = ExtendedFacing.VALUES.length; i < valuesLength; i++) {
if (checkedSetExtendedFacing(ExtendedFacing.VALUES[(j + i)%valuesLength])){ if (checkedSetExtendedFacing(ExtendedFacing.VALUES[(j + i) % valuesLength])) {
return true; return true;
} }
} }
return false; return false;
}else { } else {
return checkedSetExtendedFacing(extendedFacing); return checkedSetExtendedFacing(extendedFacing);
} }
} }
default boolean checkedSetExtendedFacing(ExtendedFacing alignment){ default boolean checkedSetExtendedFacing(ExtendedFacing alignment) {
if (isNewExtendedFacingValid(alignment)){ if (isNewExtendedFacingValid(alignment)) {
setExtendedFacing(alignment); setExtendedFacing(alignment);
return true; return true;
} }
@@ -153,31 +157,31 @@ public interface IAlignment extends IAlignmentLimits,IAlignmentProvider {
} }
default boolean isNewDirectionValid(ForgeDirection direction) { default boolean isNewDirectionValid(ForgeDirection direction) {
return isNewExtendedFacingValid(direction,getRotation(),getFlip()); return isNewExtendedFacingValid(direction, getRotation(), getFlip());
} }
default boolean isNewRotationValid(Rotation rotation){ default boolean isNewRotationValid(Rotation rotation) {
return isNewExtendedFacingValid(getDirection(),rotation,getFlip()); return isNewExtendedFacingValid(getDirection(), rotation, getFlip());
} }
default boolean isNewFlipValid(Flip flip){ default boolean isNewFlipValid(Flip flip) {
return isNewExtendedFacingValid(getDirection(),getRotation(),flip); return isNewExtendedFacingValid(getDirection(), getRotation(), flip);
} }
default boolean isExtendedFacingValid() { default boolean isExtendedFacingValid() {
return isNewExtendedFacingValid(getDirection(),getRotation(),getFlip()); return isNewExtendedFacingValid(getDirection(), getRotation(), getFlip());
} }
@Override @Override
default boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip){ default boolean isNewExtendedFacingValid(ForgeDirection direction, Rotation rotation, Flip flip) {
return getAlignmentLimits().isNewExtendedFacingValid(direction, rotation, flip); return getAlignmentLimits().isNewExtendedFacingValid(direction, rotation, flip);
} }
@Override @Override
default boolean isNewExtendedFacingValid(ExtendedFacing alignment){ default boolean isNewExtendedFacingValid(ExtendedFacing alignment) {
return getAlignmentLimits().isNewExtendedFacingValid( return getAlignmentLimits().isNewExtendedFacingValid(
alignment.getDirection(), alignment.getDirection(),
alignment.getRotation(), alignment.getRotation(),
alignment.getFlip()); alignment.getFlip());
} }
} }
@@ -1,4 +1,5 @@
package com.gtnewhorizon.structurelib.alignment; package com.gtnewhorizon.structurelib.alignment;
import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing;
import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; import com.gtnewhorizon.structurelib.alignment.enumerable.Flip;
import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation;
@@ -18,9 +19,9 @@ public interface IAlignmentLimits {
default boolean isNewExtendedFacingValid(ExtendedFacing alignment) { default boolean isNewExtendedFacingValid(ExtendedFacing alignment) {
return isNewExtendedFacingValid( return isNewExtendedFacingValid(
alignment.getDirection(), alignment.getDirection(),
alignment.getRotation(), alignment.getRotation(),
alignment.getFlip()); alignment.getFlip());
} }
static IAlignmentLimits allowOnly(ExtendedFacing... allowedFacings) { static IAlignmentLimits allowOnly(ExtendedFacing... allowedFacings) {
@@ -42,7 +43,8 @@ public interface IAlignmentLimits {
class Builder { class Builder {
protected final boolean[] validStates = new boolean[STATES_COUNT]; protected final boolean[] validStates = new boolean[STATES_COUNT];
private Builder() {} private Builder() {
}
public static Builder allowAll() { public static Builder allowAll() {
Builder b = new Builder(); Builder b = new Builder();
@@ -16,69 +16,69 @@ public class IntegerAxisSwap {
this.forFirstAxis = Direction.getAxisVector(forFirstAxis); this.forFirstAxis = Direction.getAxisVector(forFirstAxis);
this.forSecondAxis = Direction.getAxisVector(forSecondAxis); this.forSecondAxis = Direction.getAxisVector(forSecondAxis);
this.forThirdAxis = Direction.getAxisVector(forThirdAxis); this.forThirdAxis = Direction.getAxisVector(forThirdAxis);
if(abs(this.forFirstAxis.get0())+abs(this.forSecondAxis.get0())+abs(this.forThirdAxis.get0())!=1 || if (abs(this.forFirstAxis.get0()) + abs(this.forSecondAxis.get0()) + abs(this.forThirdAxis.get0()) != 1 ||
abs(this.forFirstAxis.get1())+abs(this.forSecondAxis.get1())+abs(this.forThirdAxis.get1())!=1 || abs(this.forFirstAxis.get1()) + abs(this.forSecondAxis.get1()) + abs(this.forThirdAxis.get1()) != 1 ||
abs(this.forFirstAxis.get2())+abs(this.forSecondAxis.get2())+abs(this.forThirdAxis.get2())!=1){ abs(this.forFirstAxis.get2()) + abs(this.forSecondAxis.get2()) + abs(this.forThirdAxis.get2()) != 1) {
throw new IllegalArgumentException("Axis are overlapping/missing! "+ throw new IllegalArgumentException("Axis are overlapping/missing! " +
forFirstAxis.name()+" "+ forFirstAxis.name() + " " +
forSecondAxis.name()+" "+ forSecondAxis.name() + " " +
forThirdAxis.name()); forThirdAxis.name());
} }
} }
public Vec3Impl translate(Vec3Impl point){ public Vec3Impl translate(Vec3Impl point) {
return new Vec3Impl( return new Vec3Impl(
forFirstAxis.get0()*point.get0() +forFirstAxis.get1()*point.get1() +forFirstAxis.get2()*point.get2(), forFirstAxis.get0() * point.get0() + forFirstAxis.get1() * point.get1() + forFirstAxis.get2() * point.get2(),
forSecondAxis.get0()*point.get0()+forSecondAxis.get1()*point.get1()+forSecondAxis.get2()*point.get2(), forSecondAxis.get0() * point.get0() + forSecondAxis.get1() * point.get1() + forSecondAxis.get2() * point.get2(),
forThirdAxis.get0()*point.get0() +forThirdAxis.get1()*point.get1() +forThirdAxis.get2()*point.get2() forThirdAxis.get0() * point.get0() + forThirdAxis.get1() * point.get1() + forThirdAxis.get2() * point.get2()
); );
} }
public Vec3Impl inverseTranslate(Vec3Impl point){ public Vec3Impl inverseTranslate(Vec3Impl point) {
return new Vec3Impl( return new Vec3Impl(
forFirstAxis.get0()*point.get0()+forSecondAxis.get0()*point.get1()+forThirdAxis.get0()*point.get2(), forFirstAxis.get0() * point.get0() + forSecondAxis.get0() * point.get1() + forThirdAxis.get0() * point.get2(),
forFirstAxis.get1()*point.get0()+forSecondAxis.get1()*point.get1()+forThirdAxis.get1()*point.get2(), forFirstAxis.get1() * point.get0() + forSecondAxis.get1() * point.get1() + forThirdAxis.get1() * point.get2(),
forFirstAxis.get2()*point.get0()+forSecondAxis.get2()*point.get1()+forThirdAxis.get2()*point.get2() forFirstAxis.get2() * point.get0() + forSecondAxis.get2() * point.get1() + forThirdAxis.get2() * point.get2()
); );
} }
public Vec3 translate(Vec3 point){ public Vec3 translate(Vec3 point) {
return Vec3.createVectorHelper( return Vec3.createVectorHelper(
forFirstAxis.get0()*point.xCoord +forFirstAxis.get1()*point.yCoord +forFirstAxis.get2()*point.zCoord, forFirstAxis.get0() * point.xCoord + forFirstAxis.get1() * point.yCoord + forFirstAxis.get2() * point.zCoord,
forSecondAxis.get0()*point.xCoord+forSecondAxis.get1()*point.yCoord+forSecondAxis.get2()*point.zCoord, forSecondAxis.get0() * point.xCoord + forSecondAxis.get1() * point.yCoord + forSecondAxis.get2() * point.zCoord,
forThirdAxis.get0()*point.xCoord +forThirdAxis.get1()*point.yCoord +forThirdAxis.get2()*point.zCoord forThirdAxis.get0() * point.xCoord + forThirdAxis.get1() * point.yCoord + forThirdAxis.get2() * point.zCoord
); );
} }
public Vec3 inverseTranslate(Vec3 point){ public Vec3 inverseTranslate(Vec3 point) {
return Vec3.createVectorHelper( return Vec3.createVectorHelper(
forFirstAxis.get0()*point.xCoord+forSecondAxis.get0()*point.yCoord+forThirdAxis.get0()*point.zCoord, forFirstAxis.get0() * point.xCoord + forSecondAxis.get0() * point.yCoord + forThirdAxis.get0() * point.zCoord,
forFirstAxis.get1()*point.xCoord+forSecondAxis.get1()*point.yCoord+forThirdAxis.get1()*point.zCoord, forFirstAxis.get1() * point.xCoord + forSecondAxis.get1() * point.yCoord + forThirdAxis.get1() * point.zCoord,
forFirstAxis.get2()*point.xCoord+forSecondAxis.get2()*point.yCoord+forThirdAxis.get2()*point.zCoord forFirstAxis.get2() * point.xCoord + forSecondAxis.get2() * point.yCoord + forThirdAxis.get2() * point.zCoord
); );
} }
public void translate(int[] point,int[] out){ public void translate(int[] point, int[] out) {
out[0]=forFirstAxis.get0()*point[0] +forFirstAxis.get1()*point[1] +forFirstAxis.get2()*point[2]; out[0] = forFirstAxis.get0() * point[0] + forFirstAxis.get1() * point[1] + forFirstAxis.get2() * point[2];
out[1]=forSecondAxis.get0()*point[0]+forSecondAxis.get1()*point[1]+forSecondAxis.get2()*point[2]; out[1] = forSecondAxis.get0() * point[0] + forSecondAxis.get1() * point[1] + forSecondAxis.get2() * point[2];
out[2]=forThirdAxis.get0()*point[0] +forThirdAxis.get1()*point[1] +forThirdAxis.get2()*point[2]; out[2] = forThirdAxis.get0() * point[0] + forThirdAxis.get1() * point[1] + forThirdAxis.get2() * point[2];
} }
public void inverseTranslate(int[] point,int[] out){ public void inverseTranslate(int[] point, int[] out) {
out[0]=forFirstAxis.get0()*point[0]+forSecondAxis.get0()*point[1]+forThirdAxis.get0()*point[2]; out[0] = forFirstAxis.get0() * point[0] + forSecondAxis.get0() * point[1] + forThirdAxis.get0() * point[2];
out[1]=forFirstAxis.get1()*point[0]+forSecondAxis.get1()*point[1]+forThirdAxis.get1()*point[2]; out[1] = forFirstAxis.get1() * point[0] + forSecondAxis.get1() * point[1] + forThirdAxis.get1() * point[2];
out[2]=forFirstAxis.get2()*point[0]+forSecondAxis.get2()*point[1]+forThirdAxis.get2()*point[2]; out[2] = forFirstAxis.get2() * point[0] + forSecondAxis.get2() * point[1] + forThirdAxis.get2() * point[2];
} }
public void translate(double[] point,double[] out){ public void translate(double[] point, double[] out) {
out[0]=forFirstAxis.get0()*point[0] +forFirstAxis.get1()*point[1] +forFirstAxis.get2()*point[2]; out[0] = forFirstAxis.get0() * point[0] + forFirstAxis.get1() * point[1] + forFirstAxis.get2() * point[2];
out[1]=forSecondAxis.get0()*point[0]+forSecondAxis.get1()*point[1]+forSecondAxis.get2()*point[2]; out[1] = forSecondAxis.get0() * point[0] + forSecondAxis.get1() * point[1] + forSecondAxis.get2() * point[2];
out[2]=forThirdAxis.get0()*point[0] +forThirdAxis.get1()*point[1] +forThirdAxis.get2()*point[2]; out[2] = forThirdAxis.get0() * point[0] + forThirdAxis.get1() * point[1] + forThirdAxis.get2() * point[2];
} }
public void inverseTranslate(double[] point,double[] out){ public void inverseTranslate(double[] point, double[] out) {
out[0]=forFirstAxis.get0()*point[0]+forSecondAxis.get0()*point[1]+forThirdAxis.get0()*point[2]; out[0] = forFirstAxis.get0() * point[0] + forSecondAxis.get0() * point[1] + forThirdAxis.get0() * point[2];
out[1]=forFirstAxis.get1()*point[0]+forSecondAxis.get1()*point[1]+forThirdAxis.get1()*point[2]; out[1] = forFirstAxis.get1() * point[0] + forSecondAxis.get1() * point[1] + forThirdAxis.get1() * point[2];
out[2]=forFirstAxis.get2()*point[0]+forSecondAxis.get2()*point[1]+forThirdAxis.get2()*point[2]; out[2] = forFirstAxis.get2() * point[0] + forSecondAxis.get2() * point[1] + forThirdAxis.get2() * point[2];
} }
} }
@@ -43,10 +43,10 @@ public class ConstructableUtility {
IMultiblockInfoContainer<TileEntity> iMultiblockInfoContainer = IMultiblockInfoContainer.get(tTileEntity.getClass()); IMultiblockInfoContainer<TileEntity> iMultiblockInfoContainer = IMultiblockInfoContainer.get(tTileEntity.getClass());
if (tTileEntity instanceof IAlignment) { if (tTileEntity instanceof IAlignment) {
iMultiblockInfoContainer.construct(aStack, false, tTileEntity, iMultiblockInfoContainer.construct(aStack, false, tTileEntity,
((IAlignment) tTileEntity).getExtendedFacing()); ((IAlignment) tTileEntity).getExtendedFacing());
} else { } else {
iMultiblockInfoContainer.construct(aStack, false, tTileEntity, iMultiblockInfoContainer.construct(aStack, false, tTileEntity,
ExtendedFacing.of(ForgeDirection.getOrientation(aSide))); ExtendedFacing.of(ForgeDirection.getOrientation(aSide)));
} }
} }
} }
@@ -68,10 +68,10 @@ public class ConstructableUtility {
IMultiblockInfoContainer<TileEntity> iMultiblockInfoContainer = IMultiblockInfoContainer.get(tTileEntity.getClass()); IMultiblockInfoContainer<TileEntity> iMultiblockInfoContainer = IMultiblockInfoContainer.get(tTileEntity.getClass());
if (tTileEntity instanceof IAlignment) { if (tTileEntity instanceof IAlignment) {
iMultiblockInfoContainer.construct(aStack, true, tTileEntity, iMultiblockInfoContainer.construct(aStack, true, tTileEntity,
((IAlignment) tTileEntity).getExtendedFacing()); ((IAlignment) tTileEntity).getExtendedFacing());
} else { } else {
iMultiblockInfoContainer.construct(aStack, true, tTileEntity, iMultiblockInfoContainer.construct(aStack, true, tTileEntity,
ExtendedFacing.of(ForgeDirection.getOrientation(aSide))); ExtendedFacing.of(ForgeDirection.getOrientation(aSide)));
} }
StructureLib.addClientSideChatMessages(IMultiblockInfoContainer.get(tTileEntity.getClass()).getDescription(aStack)); StructureLib.addClientSideChatMessages(IMultiblockInfoContainer.get(tTileEntity.getClass()).getDescription(aStack));
return false; return false;
@@ -6,9 +6,9 @@ import javax.annotation.Nullable;
* Implement this interface if this tile entity MIGHT be constructable * Implement this interface if this tile entity MIGHT be constructable
*/ */
public interface IConstructableProvider { public interface IConstructableProvider {
/** /**
* @return null if not constructable, an instance otherwise. * @return null if not constructable, an instance otherwise.
*/ */
@Nullable @Nullable
IConstructable getConstructable(); IConstructable getConstructable();
} }
@@ -13,11 +13,11 @@ public enum Direction {
private final ForgeDirection forgeDirection; private final ForgeDirection forgeDirection;
private final Vec3Impl axisVector; private final Vec3Impl axisVector;
public static final Direction[] VALUES=values(); public static final Direction[] VALUES = values();
Direction(ForgeDirection forgeDirection) { Direction(ForgeDirection forgeDirection) {
this.forgeDirection = forgeDirection; this.forgeDirection = forgeDirection;
axisVector=new Vec3Impl(forgeDirection.offsetX,forgeDirection.offsetY,forgeDirection.offsetZ); axisVector = new Vec3Impl(forgeDirection.offsetX, forgeDirection.offsetY, forgeDirection.offsetZ);
} }
public ForgeDirection getForgeDirection() { public ForgeDirection getForgeDirection() {
@@ -28,7 +28,7 @@ public enum Direction {
return axisVector; return axisVector;
} }
public static Vec3Impl getAxisVector(ForgeDirection forgeDirection){ public static Vec3Impl getAxisVector(ForgeDirection forgeDirection) {
return VALUES[forgeDirection.ordinal()].axisVector; return VALUES[forgeDirection.ordinal()].axisVector;
} }
} }
@@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableSet;
import com.gtnewhorizon.structurelib.alignment.IAlignment; import com.gtnewhorizon.structurelib.alignment.IAlignment;
import com.gtnewhorizon.structurelib.alignment.IntegerAxisSwap; import com.gtnewhorizon.structurelib.alignment.IntegerAxisSwap;
import com.gtnewhorizon.structurelib.util.Vec3Impl; import com.gtnewhorizon.structurelib.util.Vec3Impl;
import net.minecraft.util.StatCollector;
import net.minecraft.util.Vec3; import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.common.util.ForgeDirection;
@@ -113,19 +114,20 @@ public enum ExtendedFacing {
EAST_COUNTER_CLOCKWISE_VERTICAL("east counter clockwise vertical"), EAST_COUNTER_CLOCKWISE_VERTICAL("east counter clockwise vertical"),
EAST_COUNTER_CLOCKWISE_BOTH("east counter clockwise both"); EAST_COUNTER_CLOCKWISE_BOTH("east counter clockwise both");
public static final ExtendedFacing DEFAULT=NORTH_NORMAL_NONE; public static final ExtendedFacing DEFAULT = NORTH_NORMAL_NONE;
public static final ExtendedFacing[] VALUES = values(); public static final ExtendedFacing[] VALUES = values();
public static final Map<ForgeDirection, List<ExtendedFacing>> FOR_FACING=new HashMap<>(); public static final Map<ForgeDirection, List<ExtendedFacing>> FOR_FACING = new HashMap<>();
public static final int STATES_COUNT = VALUES.length; public static final int STATES_COUNT = VALUES.length;
static { static {
stream(values()).forEach(extendedFacing -> stream(values()).forEach(extendedFacing ->
FOR_FACING.compute(extendedFacing.direction, ((forgeDirection, extendedFacings) -> { FOR_FACING.compute(extendedFacing.direction, ((forgeDirection, extendedFacings) -> {
if (extendedFacings == null) { if (extendedFacings == null) {
extendedFacings = new ArrayList<>(); extendedFacings = new ArrayList<>();
} }
extendedFacings.add(extendedFacing); extendedFacings.add(extendedFacing);
return extendedFacings; return extendedFacings;
}))); })));
} }
private static final Map<String, ExtendedFacing> NAME_LOOKUP = stream(VALUES).collect(toMap(ExtendedFacing::getName2, (extendedFacing) -> extendedFacing)); private static final Map<String, ExtendedFacing> NAME_LOOKUP = stream(VALUES).collect(toMap(ExtendedFacing::getName2, (extendedFacing) -> extendedFacing));
@@ -142,133 +144,146 @@ public enum ExtendedFacing {
ExtendedFacing(String name) { ExtendedFacing(String name) {
this.name = name; this.name = name;
direction= Direction.VALUES[ordinal()/(ROTATIONS_COUNT*FLIPS_COUNT)].getForgeDirection(); direction = Direction.VALUES[ordinal() / (ROTATIONS_COUNT * FLIPS_COUNT)].getForgeDirection();
rotation=Rotation.VALUES[ordinal()/FLIPS_COUNT-direction.ordinal()*ROTATIONS_COUNT]; rotation = Rotation.VALUES[ordinal() / FLIPS_COUNT - direction.ordinal() * ROTATIONS_COUNT];
flip=Flip.VALUES[ordinal()%FLIPS_COUNT]; flip = Flip.VALUES[ordinal() % FLIPS_COUNT];
ForgeDirection a,b,c; ForgeDirection a, b, c;
switch (direction){ switch (direction) {
case DOWN: case DOWN:
a= ForgeDirection.WEST; a = ForgeDirection.WEST;
b= ForgeDirection.SOUTH; b = ForgeDirection.SOUTH;
c= ForgeDirection.UP; c = ForgeDirection.UP;
break; break;
case UP: case UP:
a= ForgeDirection.EAST; a = ForgeDirection.EAST;
b= ForgeDirection.SOUTH; b = ForgeDirection.SOUTH;
c= ForgeDirection.DOWN; c = ForgeDirection.DOWN;
break; break;
case NORTH: case NORTH:
a= ForgeDirection.WEST; a = ForgeDirection.WEST;
b= ForgeDirection.DOWN; b = ForgeDirection.DOWN;
c= ForgeDirection.SOUTH; c = ForgeDirection.SOUTH;
break; break;
case SOUTH: case SOUTH:
a= ForgeDirection.EAST; a = ForgeDirection.EAST;
b= ForgeDirection.DOWN; b = ForgeDirection.DOWN;
c= ForgeDirection.NORTH; c = ForgeDirection.NORTH;
break; break;
case WEST: case WEST:
a= ForgeDirection.SOUTH; a = ForgeDirection.SOUTH;
b= ForgeDirection.DOWN; b = ForgeDirection.DOWN;
c= ForgeDirection.EAST; c = ForgeDirection.EAST;
break; break;
case EAST: case EAST:
a= ForgeDirection.NORTH; a = ForgeDirection.NORTH;
b= ForgeDirection.DOWN; b = ForgeDirection.DOWN;
c= ForgeDirection.WEST; c = ForgeDirection.WEST;
break; break;
default:throw new RuntimeException("Is impossible..."); default:
throw new RuntimeException("Is impossible...");
} }
switch (flip){//This duplicates some axis swaps since flip boolean would do, but seems more convenient to use switch (flip) {//This duplicates some axis swaps since flip boolean would do, but seems more convenient to use
case HORIZONTAL: case HORIZONTAL:
a=a.getOpposite(); a = a.getOpposite();
break; break;
case BOTH: case BOTH:
a=a.getOpposite(); a = a.getOpposite();
case VERTICAL: case VERTICAL:
b=b.getOpposite(); b = b.getOpposite();
break; break;
case NONE: break; case NONE:
default:throw new RuntimeException("Even more impossible..."); break;
default:
throw new RuntimeException("Even more impossible...");
} }
switch (rotation) { switch (rotation) {
case CLOCKWISE: { case CLOCKWISE: {
ForgeDirection _a=a; ForgeDirection _a = a;
a =b; a = b;
b =_a.getOpposite(); b = _a.getOpposite();
break; break;
} }
case UPSIDE_DOWN: case UPSIDE_DOWN:
a=a.getOpposite(); a = a.getOpposite();
b=b.getOpposite(); b = b.getOpposite();
break; break;
case COUNTER_CLOCKWISE: { case COUNTER_CLOCKWISE: {
ForgeDirection _a=a; ForgeDirection _a = a;
a =b.getOpposite(); a = b.getOpposite();
b =_a; b = _a;
break; break;
} }
case NORMAL: break; case NORMAL:
break;
default: default:
throw new RuntimeException("More impossible..."); throw new RuntimeException("More impossible...");
} }
this.a=a; this.a = a;
this.b=b; this.b = b;
this.c=c; this.c = c;
integerAxisSwap =new IntegerAxisSwap(a,b,c); integerAxisSwap = new IntegerAxisSwap(a, b, c);
} }
public static ExtendedFacing of(ForgeDirection direction, Rotation rotation, Flip flip){ public static ExtendedFacing of(ForgeDirection direction, Rotation rotation, Flip flip) {
if(direction==ForgeDirection.UNKNOWN){ if (direction == ForgeDirection.UNKNOWN) {
return VALUES[IAlignment.getAlignmentIndex(ForgeDirection.NORTH, rotation, flip)]; return VALUES[IAlignment.getAlignmentIndex(ForgeDirection.NORTH, rotation, flip)];
} }
return VALUES[IAlignment.getAlignmentIndex(direction, rotation, flip)]; return VALUES[IAlignment.getAlignmentIndex(direction, rotation, flip)];
} }
public static ExtendedFacing of(ForgeDirection direction){ public static ExtendedFacing of(ForgeDirection direction) {
if(direction==ForgeDirection.UNKNOWN){ if (direction == ForgeDirection.UNKNOWN) {
return DEFAULT; return DEFAULT;
} }
return VALUES[IAlignment.getAlignmentIndex(direction, Rotation.NORMAL, Flip.NONE)]; return VALUES[IAlignment.getAlignmentIndex(direction, Rotation.NORMAL, Flip.NONE)];
} }
public static ImmutableSet<ExtendedFacing> getAllWith(ForgeDirection direction) { return LOOKUP_BY_DIRECTION.get(direction);} public static ImmutableSet<ExtendedFacing> getAllWith(ForgeDirection direction) {
public static ImmutableSet<ExtendedFacing> getAllWith(Rotation rotation) { return LOOKUP_BY_ROTATION.get(rotation);} return LOOKUP_BY_DIRECTION.get(direction);
public static ImmutableSet<ExtendedFacing> getAllWith(Flip flip) { return LOOKUP_BY_FLIP.get(flip);}
public ExtendedFacing with(ForgeDirection direction){
return of(direction,rotation,flip);
} }
public ExtendedFacing with(Rotation rotation){ public static ImmutableSet<ExtendedFacing> getAllWith(Rotation rotation) {
return of(direction,rotation,flip); return LOOKUP_BY_ROTATION.get(rotation);
} }
public ExtendedFacing with(Flip flip){ public static ImmutableSet<ExtendedFacing> getAllWith(Flip flip) {
return of(direction,rotation,flip); return LOOKUP_BY_FLIP.get(flip);
}
public ExtendedFacing with(ForgeDirection direction) {
return of(direction, rotation, flip);
}
public ExtendedFacing with(Rotation rotation) {
return of(direction, rotation, flip);
}
public ExtendedFacing with(Flip flip) {
return of(direction, rotation, flip);
} }
public ExtendedFacing getOppositeDirection() { public ExtendedFacing getOppositeDirection() {
return of(direction.getOpposite(),rotation,flip); return of(direction.getOpposite(), rotation, flip);
} }
public ExtendedFacing getOppositeRotation() { public ExtendedFacing getOppositeRotation() {
return of(direction,rotation.getOpposite(),flip); return of(direction, rotation.getOpposite(), flip);
} }
public ExtendedFacing getOppositeFlip() { public ExtendedFacing getOppositeFlip() {
return of(direction,rotation,flip.getOpposite()); return of(direction, rotation, flip.getOpposite());
} }
/** /**
* Gets the same effective facing achieved by different rot/flip combo * Gets the same effective facing achieved by different rot/flip combo
*
* @return same effective facing, but different enum value * @return same effective facing, but different enum value
*/ */
public ExtendedFacing getDuplicate(){ public ExtendedFacing getDuplicate() {
return of(direction,rotation.getOpposite(),flip.getOpposite()); return of(direction, rotation.getOpposite(), flip.getOpposite());
} }
public int getIndex(){ public int getIndex() {
return ordinal(); return ordinal();
} }
@@ -276,6 +291,10 @@ public enum ExtendedFacing {
return this.name; return this.name;
} }
public String getLocalizedName() {
return StatCollector.translateToLocal("structurelib.facing." + getIndex());
}
public static ExtendedFacing byName(String name) { public static ExtendedFacing byName(String name) {
return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT)); return name == null ? null : NAME_LOOKUP.get(name.toLowerCase(Locale.ROOT));
} }
@@ -302,39 +321,47 @@ public enum ExtendedFacing {
/** /**
* Translates relative to front facing offset to world offset * Translates relative to front facing offset to world offset
*
* @param abcOffset A,B,C offset (facing relative L-->R,U-->D,F-->B) * @param abcOffset A,B,C offset (facing relative L-->R,U-->D,F-->B)
* @return X,Y,Z offset in world * @return X, Y, Z offset in world
*/ */
public Vec3 getWorldOffset(Vec3 abcOffset) { public Vec3 getWorldOffset(Vec3 abcOffset) {
return integerAxisSwap.inverseTranslate(abcOffset); return integerAxisSwap.inverseTranslate(abcOffset);
} }
public Vec3Impl getWorldOffset(Vec3Impl abcOffset) { public Vec3Impl getWorldOffset(Vec3Impl abcOffset) {
return integerAxisSwap.inverseTranslate(abcOffset); return integerAxisSwap.inverseTranslate(abcOffset);
} }
public void getWorldOffset(int[] point,int[] out){
integerAxisSwap.inverseTranslate(point,out); public void getWorldOffset(int[] point, int[] out) {
integerAxisSwap.inverseTranslate(point, out);
} }
public void getWorldOffset(double[] point,double[] out){
integerAxisSwap.inverseTranslate(point,out); public void getWorldOffset(double[] point, double[] out) {
integerAxisSwap.inverseTranslate(point, out);
} }
/** /**
* Translates world offset to relative front facing offset * Translates world offset to relative front facing offset
*
* @param xyzOffset X,Y,Z offset in world * @param xyzOffset X,Y,Z offset in world
* @return A,B,C offset (facing relative L-->R,U-->D,F-->B) * @return A, B, C offset (facing relative L-->R,U-->D,F-->B)
*/ */
public Vec3 getOffsetABC(Vec3 xyzOffset){ public Vec3 getOffsetABC(Vec3 xyzOffset) {
return integerAxisSwap.translate(xyzOffset); return integerAxisSwap.translate(xyzOffset);
} }
public Vec3Impl getOffsetABC(Vec3Impl xyzOffset){
public Vec3Impl getOffsetABC(Vec3Impl xyzOffset) {
return integerAxisSwap.translate(xyzOffset); return integerAxisSwap.translate(xyzOffset);
} }
public void getOffsetABC(int[] point,int[] out){
integerAxisSwap.translate(point,out); public void getOffsetABC(int[] point, int[] out) {
integerAxisSwap.translate(point, out);
} }
public void getOffsetABC(double[] point,double[] out){
integerAxisSwap.translate(point,out); public void getOffsetABC(double[] point, double[] out) {
integerAxisSwap.translate(point, out);
} }
public IntegerAxisSwap getIntegerAxisSwap() { public IntegerAxisSwap getIntegerAxisSwap() {
@@ -26,7 +26,7 @@ public enum Flip {
this.name = nameIn; this.name = nameIn;
} }
public int getIndex(){ public int getIndex() {
return ordinal(); return ordinal();
} }
@@ -58,19 +58,19 @@ public enum Flip {
return this.name; return this.name;
} }
public boolean isNotFlipped(){ public boolean isNotFlipped() {
return this==NONE; return this == NONE;
} }
public boolean isBothFlipped(){ public boolean isBothFlipped() {
return this==BOTH; return this == BOTH;
} }
public boolean isHorizontallyFlipped() { public boolean isHorizontallyFlipped() {
return this==HORIZONTAL || isBothFlipped(); return this == HORIZONTAL || isBothFlipped();
} }
public boolean isVerticallyFliped() { public boolean isVerticallyFliped() {
return this==VERTICAL || isBothFlipped(); return this == VERTICAL || isBothFlipped();
} }
} }
@@ -26,7 +26,7 @@ public enum Rotation {
this.name = nameIn; this.name = nameIn;
} }
public int getIndex(){ public int getIndex() {
return ordinal(); return ordinal();
} }
@@ -58,19 +58,19 @@ public enum Rotation {
return this.name; return this.name;
} }
public boolean isNotRotated(){ public boolean isNotRotated() {
return this==NORMAL; return this == NORMAL;
} }
public boolean isClockwise(){ public boolean isClockwise() {
return this==CLOCKWISE; return this == CLOCKWISE;
} }
public boolean isCounterClockwise(){ public boolean isCounterClockwise() {
return this==COUNTER_CLOCKWISE; return this == COUNTER_CLOCKWISE;
} }
public boolean isUpsideDown(){ public boolean isUpsideDown() {
return this==UPSIDE_DOWN; return this == UPSIDE_DOWN;
} }
} }
@@ -16,52 +16,52 @@ import net.minecraft.world.IBlockAccess;
import java.util.List; import java.util.List;
public class BlockHint extends Block { public class BlockHint extends Block {
private static final IIcon[] hint = new IIcon[16]; private static final IIcon[] hint = new IIcon[16];
public BlockHint() { public BlockHint() {
super(Material.iron); super(Material.iron);
setBlockName("structurelib.blockhint"); setBlockName("structurelib.blockhint");
setCreativeTab(StructureLib.creativeTab); setCreativeTab(StructureLib.creativeTab);
} }
@Override @Override
public void registerBlockIcons(IIconRegister aIconRegister) { public void registerBlockIcons(IIconRegister aIconRegister) {
//super.registerBlockIcons(aIconRegister); //super.registerBlockIcons(aIconRegister);
hint[0] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_0"); hint[0] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_0");
hint[1] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_1"); hint[1] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_1");
hint[2] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_2"); hint[2] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_2");
hint[3] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_3"); hint[3] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_3");
hint[4] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_4"); hint[4] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_4");
hint[5] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_5"); hint[5] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_5");
hint[6] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_6"); hint[6] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_6");
hint[7] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_7"); hint[7] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_7");
hint[8] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_8"); hint[8] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_8");
hint[9] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_9"); hint[9] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_9");
hint[10] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_10"); hint[10] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_10");
hint[11] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_11"); hint[11] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_11");
hint[12] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_DEFAULT"); hint[12] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_DEFAULT");
hint[13] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_AIR"); hint[13] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_AIR");
hint[14] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_NOAIR"); hint[14] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_NOAIR");
hint[15] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_ERROR"); hint[15] = aIconRegister.registerIcon(StructureLibAPI.MOD_ID + ":iconsets/HINT_ERROR");
} }
@Override @Override
public IIcon getIcon(int aSide, int aMeta) { public IIcon getIcon(int aSide, int aMeta) {
return hint[aMeta]; return hint[aMeta];
} }
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public IIcon getIcon(IBlockAccess aWorld, int xCoord, int yCoord, int zCoord, int aSide) { public IIcon getIcon(IBlockAccess aWorld, int xCoord, int yCoord, int zCoord, int aSide) {
int tMeta = aWorld.getBlockMetadata(xCoord, yCoord, zCoord); int tMeta = aWorld.getBlockMetadata(xCoord, yCoord, zCoord);
return getIcon(aSide, tMeta); return getIcon(aSide, tMeta);
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void getSubBlocks(Item aItem, CreativeTabs par2CreativeTabs, List aList) { public void getSubBlocks(Item aItem, CreativeTabs par2CreativeTabs, List aList) {
for (int i = 0; i <= 15; i++) { for (int i = 0; i <= 15; i++) {
aList.add(new ItemStack(aItem, 1, i)); aList.add(new ItemStack(aItem, 1, i));
} }
} }
} }
@@ -15,14 +15,13 @@ import org.lwjgl.opengl.GL11;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class EntityFXBlockHint extends EntityFX { public class EntityFXBlockHint extends EntityFX {
private IIcon[] icons; private IIcon[] icons;
private short[] mRGBa = {255,255,255,0}; private short[] mRGBa = {255, 255, 255, 0};
public EntityFXBlockHint(World world){ public EntityFXBlockHint(World world) {
this(world,0,0,0, Blocks.stone,0); this(world, 0, 0, 0, Blocks.stone, 0);
} }
/** /**
*
* @param world * @param world
* @param x * @param x
* @param y * @param y
@@ -37,11 +36,11 @@ public class EntityFXBlockHint extends EntityFX {
prevPosZ = posZ; prevPosZ = posZ;
noClip = true; noClip = true;
particleMaxAge = 2000 + StructureLib.RANDOM.nextInt(200); particleMaxAge = 2000 + StructureLib.RANDOM.nextInt(200);
this.icons=icons; this.icons = icons;
} }
public EntityFXBlockHint(World world, int x, int y, int z, Block block, int meta) { public EntityFXBlockHint(World world, int x, int y, int z, Block block, int meta) {
super(world, x+.25, y+.5, z+.25); super(world, x + .25, y + .5, z + .25);
particleGravity = 0; particleGravity = 0;
prevPosX = posX; prevPosX = posX;
prevPosY = posY; prevPosY = posY;
@@ -54,8 +53,8 @@ public class EntityFXBlockHint extends EntityFX {
} }
} }
public EntityFXBlockHint withColorTint(short[] coloure){ public EntityFXBlockHint withColorTint(short[] coloure) {
this.mRGBa =coloure; this.mRGBa = coloure;
return this; return this;
} }
@@ -71,15 +70,15 @@ public class EntityFXBlockHint extends EntityFX {
//var8, var9 - X U //var8, var9 - X U
//var 10, var 11 - Y V //var 10, var 11 - Y V
for(int i=0;i<6;i++){ for (int i = 0; i < 6; i++) {
if(icons[i]==null) { if (icons[i] == null) {
continue; continue;
} }
double u=icons[i].getMinU(); double u = icons[i].getMinU();
double U=icons[i].getMaxU(); double U = icons[i].getMaxU();
double v=icons[i].getMinV(); double v = icons[i].getMinV();
double V=icons[i].getMaxV(); double V = icons[i].getMaxV();
switch (i){//{DOWN, UP, NORTH, SOUTH, WEST, EAST} switch (i) {//{DOWN, UP, NORTH, SOUTH, WEST, EAST}
case 0: case 0:
tes.addVertexWithUV(X, Y, Z + size, u, V); tes.addVertexWithUV(X, Y, Z + size, u, V);
tes.addVertexWithUV(X, Y, Z, u, v); tes.addVertexWithUV(X, Y, Z, u, v);
@@ -129,7 +128,7 @@ public class EntityFXBlockHint extends EntityFX {
@Override @Override
public boolean shouldRenderInPass(int pass) { public boolean shouldRenderInPass(int pass) {
return pass==2; return pass == 2;
} }
@Override @Override
@@ -6,31 +6,27 @@ import net.minecraft.client.particle.EntityFX;
import net.minecraft.world.World; import net.minecraft.world.World;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class WeightlessParticleFX extends EntityFX public class WeightlessParticleFX extends EntityFX {
{ public WeightlessParticleFX(World p_i1205_1_, double p_i1205_2_, double p_i1205_4_, double p_i1205_6_, double p_i1205_8_, double p_i1205_10_, double p_i1205_12_) {
public WeightlessParticleFX(World p_i1205_1_, double p_i1205_2_, double p_i1205_4_, double p_i1205_6_, double p_i1205_8_, double p_i1205_10_, double p_i1205_12_)
{
super(p_i1205_1_, p_i1205_2_, p_i1205_4_, p_i1205_6_, p_i1205_8_, p_i1205_10_, p_i1205_12_); super(p_i1205_1_, p_i1205_2_, p_i1205_4_, p_i1205_6_, p_i1205_8_, p_i1205_10_, p_i1205_12_);
this.motionX = p_i1205_8_ + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.05F); this.motionX = p_i1205_8_ + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F);
this.motionY = p_i1205_10_ + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.05F); this.motionY = p_i1205_10_ + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F);
this.motionZ = p_i1205_12_ + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.05F); this.motionZ = p_i1205_12_ + (double) ((float) (Math.random() * 2.0D - 1.0D) * 0.05F);
this.particleRed = this.particleGreen = this.particleBlue = this.rand.nextFloat() * 0.3F + 0.7F; this.particleRed = this.particleGreen = this.particleBlue = this.rand.nextFloat() * 0.3F + 0.7F;
this.particleScale = this.rand.nextFloat() * this.rand.nextFloat() * 6.0F + 1.0F; this.particleScale = this.rand.nextFloat() * this.rand.nextFloat() * 6.0F + 1.0F;
this.particleMaxAge = (int)(16.0D / ((double)this.rand.nextFloat() * 0.8D + 0.2D)) + 2; this.particleMaxAge = (int) (16.0D / ((double) this.rand.nextFloat() * 0.8D + 0.2D)) + 2;
this.noClip=true; this.noClip = true;
} }
/** /**
* Called to update the entity's position/logic. * Called to update the entity's position/logic.
*/ */
public void onUpdate() public void onUpdate() {
{
this.prevPosX = this.posX; this.prevPosX = this.posX;
this.prevPosY = this.posY; this.prevPosY = this.posY;
this.prevPosZ = this.posZ; this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge) if (this.particleAge++ >= this.particleMaxAge) {
{
this.setDead(); this.setDead();
} }
@@ -12,55 +12,55 @@ import java.util.List;
import static net.minecraft.util.StatCollector.translateToLocal; import static net.minecraft.util.StatCollector.translateToLocal;
public class ItemBlockHint extends ItemBlock { public class ItemBlockHint extends ItemBlock {
public ItemBlockHint(Block p_i45328_1_) { public ItemBlockHint(Block p_i45328_1_) {
super(p_i45328_1_); super(p_i45328_1_);
setMaxDamage(0); setMaxDamage(0);
setHasSubtypes(true); setHasSubtypes(true);
setCreativeTab(CreativeTabs.tabBlock); setCreativeTab(CreativeTabs.tabBlock);
} }
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) { public void addInformation(ItemStack aStack, EntityPlayer aPlayer, List aList, boolean aF3_H) {
aList.add(translateToLocal("structurelib.blockhint.desc.0"));//Helps while building aList.add(translateToLocal("structurelib.blockhint.desc.0"));//Helps while building
switch (aStack.getItemDamage()) { switch (aStack.getItemDamage()) {
case 0: case 0:
case 1: case 1:
case 2: case 2:
case 3: case 3:
case 4: case 4:
case 5: case 5:
case 6: case 6:
case 7: case 7:
case 8: case 8:
case 9: case 9:
case 10: case 10:
case 11: case 11:
aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.1"));//Placeholder for a certain group. aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.1"));//Placeholder for a certain group.
break; break;
case 12: case 12:
aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.2"));//General placeholder. aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.2"));//General placeholder.
break; break;
case 13: case 13:
aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.3"));//Make sure it contains Air material. aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.3"));//Make sure it contains Air material.
break; break;
case 14: case 14:
aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.4"));//Make sure it does not contain Air material. aList.add(EnumChatFormatting.AQUA.toString() + EnumChatFormatting.BOLD + translateToLocal("structurelib.blockhint.desc.4"));//Make sure it does not contain Air material.
break; break;
case 15: case 15:
aList.add(EnumChatFormatting.BLUE.toString() + translateToLocal("structurelib.blockhint.desc.5"));//ERROR, what did u expect? aList.add(EnumChatFormatting.BLUE.toString() + translateToLocal("structurelib.blockhint.desc.5"));//ERROR, what did u expect?
break; break;
default://WTF? default://WTF?
aList.add("Damn son where did you get that!?"); aList.add("Damn son where did you get that!?");
aList.add(EnumChatFormatting.BLUE.toString() + "From outer space... I guess..."); aList.add(EnumChatFormatting.BLUE.toString() + "From outer space... I guess...");
} }
} }
public int getMetadata(int aMeta) { public int getMetadata(int aMeta) {
return aMeta; return aMeta;
} }
public String getUnlocalizedName(ItemStack aStack) { public String getUnlocalizedName(ItemStack aStack) {
return this.field_150939_a.getUnlocalizedName() + "." + getDamage(aStack); return this.field_150939_a.getUnlocalizedName() + "." + getDamage(aStack);
} }
} }
@@ -16,23 +16,23 @@ import static com.gtnewhorizon.structurelib.StructureLibAPI.MOD_ID;
import static net.minecraft.util.StatCollector.translateToLocal; import static net.minecraft.util.StatCollector.translateToLocal;
public class ItemFrontRotationTool extends Item { public class ItemFrontRotationTool extends Item {
public ItemFrontRotationTool() { public ItemFrontRotationTool() {
setMaxStackSize(1); setMaxStackSize(1);
setUnlocalizedName("structurelib.frontRotationTool"); setUnlocalizedName("structurelib.frontRotationTool");
setTextureName(MOD_ID + ":itemFrontRotationTool"); setTextureName(MOD_ID + ":itemFrontRotationTool");
setCreativeTab(StructureLib.creativeTab); setCreativeTab(StructureLib.creativeTab);
} }
@Override @Override
public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) { public boolean onItemUseFirst(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) {
return AlignmentUtility.handle(player, world, x, y, z); return AlignmentUtility.handle(player, world, x, y, z);
} }
@Override @Override
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List aList, boolean p_77624_4_) { public void addInformation(ItemStack p_77624_1_, EntityPlayer p_77624_2_, List aList, boolean p_77624_4_) {
aList.add(translateToLocal("item.structurelib.frontRotationTool.desc.0"));//Triggers Front Rotation Interface aList.add(translateToLocal("item.structurelib.frontRotationTool.desc.0"));//Triggers Front Rotation Interface
aList.add(EnumChatFormatting.BLUE + translateToLocal("item.structurelib.frontRotationTool.desc.1"));//Rotates only the front panel, aList.add(EnumChatFormatting.BLUE + translateToLocal("item.structurelib.frontRotationTool.desc.1"));//Rotates only the front panel,
aList.add(EnumChatFormatting.BLUE + translateToLocal("item.structurelib.frontRotationTool.desc.2"));//which allows structure rotation. aList.add(EnumChatFormatting.BLUE + translateToLocal("item.structurelib.frontRotationTool.desc.2"));//which allows structure rotation.
} }
} }
@@ -7,20 +7,35 @@ import net.minecraft.util.IIcon;
import net.minecraft.world.World; import net.minecraft.world.World;
public class CommonProxy { public class CommonProxy {
public void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa){} public void hintParticleTinted(World w, int x, int y, int z, IIcon[] icons, short[] RGBa) {
public void hintParticleTinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa){} }
public void hintParticle(World w, int x, int y, int z, IIcon[] icons){}
public void hintParticle(World w, int x, int y, int z, Block block, int meta){}
public EntityPlayer getCurrentPlayer() {
return null;
}
public boolean isCurrentPlayer(EntityPlayer player) {
return false;
}
public void addClientSideChatMessages(String... messages){
}
public void startHinting(World w) {}
public void endHinting(World w) {}
public void preInit(FMLPreInitializationEvent e) {} public void hintParticleTinted(World w, int x, int y, int z, Block block, int meta, short[] RGBa) {
}
public void hintParticle(World w, int x, int y, int z, IIcon[] icons) {
}
public void hintParticle(World w, int x, int y, int z, Block block, int meta) {
}
public EntityPlayer getCurrentPlayer() {
return null;
}
public boolean isCurrentPlayer(EntityPlayer player) {
return false;
}
public void addClientSideChatMessages(String... messages) {
}
public void startHinting(World w) {
}
public void endHinting(World w) {
}
public void preInit(FMLPreInitializationEvent e) {
}
} }
@@ -3,5 +3,5 @@ package com.gtnewhorizon.structurelib.structure;
import net.minecraft.world.World; import net.minecraft.world.World;
public interface IBlockPosConsumer { public interface IBlockPosConsumer {
void consume(World world, int x, int y, int z); void consume(World world, int x, int y, int z);
} }
@@ -4,15 +4,15 @@ import net.minecraft.block.Block;
import net.minecraft.world.World; import net.minecraft.world.World;
public interface ICustomBlockSetting { public interface ICustomBlockSetting {
/** /**
* Default block setting calls {@link World#setBlock(int x, int y, int z, Block block, int meta, int updateType)} like: * Default block setting calls {@link World#setBlock(int x, int y, int z, Block block, int meta, int updateType)} like:
* {@code world.setBlock(x,y,z,this/block,meta,2)} where updateType 2 means to update lighting and stuff * {@code world.setBlock(x,y,z,this/block,meta,2)} where updateType 2 means to update lighting and stuff
* *
* @param world world that should be affected * @param world world that should be affected
* @param x x position to set * @param x x position to set
* @param y y position to set * @param y y position to set
* @param z z position to set * @param z z position to set
* @param meta required meta * @param meta required meta
*/ */
void setBlock(World world, int x, int y, int z, int meta); void setBlock(World world, int x, int y, int z, int meta);
} }
@@ -10,166 +10,169 @@ import java.util.Arrays;
import static com.gtnewhorizon.structurelib.StructureLib.DEBUG_MODE; import static com.gtnewhorizon.structurelib.StructureLib.DEBUG_MODE;
public interface IStructureDefinition<T> { public interface IStructureDefinition<T> {
/** /**
* Used internally * Used internally
* * <p>
* Might, but is not required, to throw {@link java.util.NoSuchElementException} if the given structure piece is not found. * Might, but is not required, to throw {@link java.util.NoSuchElementException} if the given structure piece is not found.
* *
* @param name same name as for other methods here * @param name same name as for other methods here
* @return the array of elements to process * @return the array of elements to process
* @throws java.util.NoSuchElementException if the given structure piece is not found and the moon phase perfectly matches * @throws java.util.NoSuchElementException if the given structure piece is not found and the moon phase perfectly matches
*/ */
IStructureElement<T>[] getStructureFor(String name); IStructureElement<T>[] getStructureFor(String name);
default boolean check(T object, String piece, World world, ExtendedFacing extendedFacing, default boolean check(T object, String piece, World world, ExtendedFacing extendedFacing,
int basePositionX, int basePositionY, int basePositionZ, int basePositionX, int basePositionY, int basePositionZ,
int basePositionA, int basePositionB, int basePositionC, int basePositionA, int basePositionB, int basePositionC,
boolean forceCheckAllBlocks) { boolean forceCheckAllBlocks) {
return iterate(object, null, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ, return iterate(object, null, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
basePositionA, basePositionB, basePositionC, false, forceCheckAllBlocks); basePositionA, basePositionB, basePositionC, false, forceCheckAllBlocks);
} }
default boolean hints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, default boolean hints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing,
int basePositionX, int basePositionY, int basePositionZ, int basePositionX, int basePositionY, int basePositionZ,
int basePositionA, int basePositionB, int basePositionC) { int basePositionA, int basePositionB, int basePositionC) {
return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ, return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
basePositionA, basePositionB, basePositionC, true, null); basePositionA, basePositionB, basePositionC, true, null);
} }
default boolean build(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, default boolean build(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing,
int basePositionX, int basePositionY, int basePositionZ, int basePositionX, int basePositionY, int basePositionZ,
int basePositionA, int basePositionB, int basePositionC) { int basePositionA, int basePositionB, int basePositionC) {
return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ, return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
basePositionA, basePositionB, basePositionC, false, null); basePositionA, basePositionB, basePositionC, false, null);
} }
default boolean buildOrHints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing, default boolean buildOrHints(T object, ItemStack trigger, String piece, World world, ExtendedFacing extendedFacing,
int basePositionX, int basePositionY, int basePositionZ, int basePositionX, int basePositionY, int basePositionZ,
int basePositionA, int basePositionB, int basePositionC, int basePositionA, int basePositionB, int basePositionC,
boolean hintsOnly) { boolean hintsOnly) {
return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ, return iterate(object, trigger, getStructureFor(piece), world, extendedFacing, basePositionX, basePositionY, basePositionZ,
basePositionA, basePositionB, basePositionC, hintsOnly, null); basePositionA, basePositionB, basePositionC, hintsOnly, null);
} }
static <T> boolean iterate(T object, ItemStack trigger, IStructureElement<T>[] elements, World world, ExtendedFacing extendedFacing, static <T> boolean iterate(T object, ItemStack trigger, IStructureElement<T>[] elements, World world, ExtendedFacing extendedFacing,
int basePositionX, int basePositionY, int basePositionZ, int basePositionX, int basePositionY, int basePositionZ,
int basePositionA, int basePositionB, int basePositionC, int basePositionA, int basePositionB, int basePositionC,
boolean hintsOnly, Boolean checkBlocksIfNotNullForceCheckAllIfTrue) { boolean hintsOnly, Boolean checkBlocksIfNotNullForceCheckAllIfTrue) {
if (world.isRemote ^ hintsOnly) { if (world.isRemote ^ hintsOnly) {
return false; return false;
} }
//change base position to base offset //change base position to base offset
basePositionA = -basePositionA; basePositionA = -basePositionA;
basePositionB = -basePositionB; basePositionB = -basePositionB;
basePositionC = -basePositionC; basePositionC = -basePositionC;
int[] abc = new int[]{basePositionA, basePositionB, basePositionC}; int[] abc = new int[]{basePositionA, basePositionB, basePositionC};
int[] xyz = new int[3]; int[] xyz = new int[3];
if (checkBlocksIfNotNullForceCheckAllIfTrue != null) { if (checkBlocksIfNotNullForceCheckAllIfTrue != null) {
if (checkBlocksIfNotNullForceCheckAllIfTrue) { if (checkBlocksIfNotNullForceCheckAllIfTrue) {
for (IStructureElement<T> element : elements) { for (IStructureElement<T> element : elements) {
if (element.isNavigating()) { if (element.isNavigating()) {
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA(); abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB(); abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC(); abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
} else { } else {
extendedFacing.getWorldOffset(abc, xyz); extendedFacing.getWorldOffset(abc, xyz);
xyz[0] += basePositionX; xyz[0] += basePositionX;
xyz[1] += basePositionY; xyz[1] += basePositionY;
xyz[2] += basePositionZ; xyz[2] += basePositionZ;
if (world.blockExists(xyz[0], xyz[1], xyz[2])) { if (world.blockExists(xyz[0], xyz[1], xyz[2])) {
if (!element.check(object, world, xyz[0], xyz[1], xyz[2])) { if (!element.check(object, world, xyz[0], xyz[1], xyz[2])) {
if (DEBUG_MODE) { if (DEBUG_MODE) {
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] failed @ " + StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] failed @ " +
Arrays.toString(xyz) + " " + Arrays.toString(abc)); Arrays.toString(xyz) + " " + Arrays.toString(abc));
} }
return false; return false;
} }
} else { } else {
if (DEBUG_MODE) { if (DEBUG_MODE) {
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] !blockExists @ " + StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] !blockExists @ " +
Arrays.toString(xyz) + " " + Arrays.toString(abc)); Arrays.toString(xyz) + " " + Arrays.toString(abc));
} }
return false; return false;
} }
abc[0] += 1; abc[0] += 1;
} }
} }
} else { } else {
for (IStructureElement<T> element : elements) { for (IStructureElement<T> element : elements) {
if (element.isNavigating()) { if (element.isNavigating()) {
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA(); abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB(); abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC(); abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
} else { } else {
extendedFacing.getWorldOffset(abc, xyz); extendedFacing.getWorldOffset(abc, xyz);
xyz[0] += basePositionX; xyz[0] += basePositionX;
xyz[1] += basePositionY; xyz[1] += basePositionY;
xyz[2] += basePositionZ; xyz[2] += basePositionZ;
if (world.blockExists(xyz[0], xyz[1], xyz[2])) { if (world.blockExists(xyz[0], xyz[1], xyz[2])) {
if (!element.check(object, world, xyz[0], xyz[1], xyz[2])) { if (!element.check(object, world, xyz[0], xyz[1], xyz[2])) {
if (DEBUG_MODE) { if (DEBUG_MODE) {
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] failed @ " + StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] failed @ " +
Arrays.toString(xyz) + " " + Arrays.toString(abc)); Arrays.toString(xyz) + " " + Arrays.toString(abc));
} }
return false; return false;
} }
} else { } else {
if (DEBUG_MODE) { if (DEBUG_MODE) {
StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] !blockExists @ " + StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] !blockExists @ " +
Arrays.toString(xyz) + " " + Arrays.toString(abc)); Arrays.toString(xyz) + " " + Arrays.toString(abc));
} }
} }
abc[0] += 1; abc[0] += 1;
} }
} }
} }
} else { if (DEBUG_MODE) {
if (hintsOnly) { StructureLib.LOGGER.info("Multi [" + basePositionX + ", " + basePositionY + ", " + basePositionZ + "] pass");
for (IStructureElement<T> element : elements) { }
if (element.isNavigating()) { } else {
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA(); if (hintsOnly) {
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB(); for (IStructureElement<T> element : elements) {
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC(); if (element.isNavigating()) {
} else { abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
extendedFacing.getWorldOffset(abc, xyz); abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
xyz[0] += basePositionX; abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
xyz[1] += basePositionY; } else {
xyz[2] += basePositionZ; extendedFacing.getWorldOffset(abc, xyz);
xyz[0] += basePositionX;
xyz[1] += basePositionY;
xyz[2] += basePositionZ;
element.spawnHint(object, world, xyz[0], xyz[1], xyz[2], trigger); element.spawnHint(object, world, xyz[0], xyz[1], xyz[2], trigger);
abc[0] += 1; abc[0] += 1;
} }
} }
} else { } else {
for (IStructureElement<T> element : elements) { for (IStructureElement<T> element : elements) {
if (element.isNavigating()) { if (element.isNavigating()) {
abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA(); abc[0] = (element.resetA() ? basePositionA : abc[0]) + element.getStepA();
abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB(); abc[1] = (element.resetB() ? basePositionB : abc[1]) + element.getStepB();
abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC(); abc[2] = (element.resetC() ? basePositionC : abc[2]) + element.getStepC();
} else { } else {
extendedFacing.getWorldOffset(abc, xyz); extendedFacing.getWorldOffset(abc, xyz);
xyz[0] += basePositionX; xyz[0] += basePositionX;
xyz[1] += basePositionY; xyz[1] += basePositionY;
xyz[2] += basePositionZ; xyz[2] += basePositionZ;
if (world.blockExists(xyz[0], xyz[1], xyz[2])) { if (world.blockExists(xyz[0], xyz[1], xyz[2])) {
element.placeBlock(object, world, xyz[0], xyz[1], xyz[2], trigger); element.placeBlock(object, world, xyz[0], xyz[1], xyz[2], trigger);
} }
abc[0] += 1; abc[0] += 1;
} }
} }
} }
} }
return true; return true;
} }
static <T> StructureDefinition.Builder<T> builder() { static <T> StructureDefinition.Builder<T> builder() {
return StructureDefinition.builder(); return StructureDefinition.builder();
} }
} }
@@ -7,37 +7,37 @@ import net.minecraft.world.World;
* Use StructureUtility to instantiate * Use StructureUtility to instantiate
*/ */
public interface IStructureElement<T> { public interface IStructureElement<T> {
boolean check(T t, World world, int x, int y, int z); boolean check(T t, World world, int x, int y, int z);
boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger); boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger);
boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger); boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger);
default int getStepA() { default int getStepA() {
return 1; return 1;
} }
default int getStepB() { default int getStepB() {
return 0; return 0;
} }
default int getStepC() { default int getStepC() {
return 0; return 0;
} }
default boolean resetA() { default boolean resetA() {
return false; return false;
} }
default boolean resetB() { default boolean resetB() {
return false; return false;
} }
default boolean resetC() { default boolean resetC() {
return false; return false;
} }
default boolean isNavigating() { default boolean isNavigating() {
return false; return false;
} }
} }
@@ -7,35 +7,35 @@ import net.minecraft.world.World;
* Use StructureUtility to instantiate * Use StructureUtility to instantiate
*/ */
public interface IStructureElementChain<T> extends IStructureElement<T> { public interface IStructureElementChain<T> extends IStructureElement<T> {
IStructureElement<T>[] fallbacks(); IStructureElement<T>[] fallbacks();
@Override @Override
default boolean check(T t, World world, int x, int y, int z) { default boolean check(T t, World world, int x, int y, int z) {
for (IStructureElement<T> fallback : fallbacks()) { for (IStructureElement<T> fallback : fallbacks()) {
if (fallback.check(t, world, x, y, z)) { if (fallback.check(t, world, x, y, z)) {
return true; return true;
} }
} }
return false; return false;
} }
@Override @Override
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
for (IStructureElement<T> fallback : fallbacks()) { for (IStructureElement<T> fallback : fallbacks()) {
if (fallback.spawnHint(t, world, x, y, z, trigger)) { if (fallback.spawnHint(t, world, x, y, z, trigger)) {
return true; return true;
} }
} }
return false; return false;
} }
@Override @Override
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
for (IStructureElement<T> fallback : fallbacks()) { for (IStructureElement<T> fallback : fallbacks()) {
if (fallback.placeBlock(t, world, x, y, z, trigger)) { if (fallback.placeBlock(t, world, x, y, z, trigger)) {
return true; return true;
} }
} }
return false; return false;
} }
} }
@@ -4,13 +4,13 @@ import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
public interface IStructureElementCheckOnly<T> extends IStructureElement<T> { public interface IStructureElementCheckOnly<T> extends IStructureElement<T> {
@Override @Override
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return false; return false;
} }
@Override @Override
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return false; return false;
} }
} }
@@ -4,8 +4,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.world.World; import net.minecraft.world.World;
public interface IStructureElementNoPlacement<T> extends IStructureElement<T> { public interface IStructureElementNoPlacement<T> extends IStructureElement<T> {
@Override @Override
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return false; return false;
} }
} }
@@ -7,22 +7,22 @@ import net.minecraft.world.World;
* Use StructureUtility to instantiate * Use StructureUtility to instantiate
*/ */
interface IStructureNavigate<T> extends IStructureElement<T> { interface IStructureNavigate<T> extends IStructureElement<T> {
@Override @Override
default boolean check(T t, World world, int x, int y, int z) { default boolean check(T t, World world, int x, int y, int z) {
return true; return true;
} }
@Override @Override
default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { default boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return true; return true;
} }
@Override @Override
default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { default boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return true; return true;
} }
default boolean isNavigating() { default boolean isNavigating() {
return true; return true;
} }
} }
@@ -4,6 +4,7 @@ import net.minecraft.block.Block;
/** /**
* a function to extract tier info from a block. * a function to extract tier info from a block.
*
* @param <TIER> * @param <TIER>
*/ */
@FunctionalInterface @FunctionalInterface
@@ -5,8 +5,9 @@ package com.gtnewhorizon.structurelib.structure;
* temporary states that don't need to live in your main context, which would usually live for the whole lifetime of the * temporary states that don't need to live in your main context, which would usually live for the whole lifetime of the
* structure than just during structure check. Usually just save some few bytes, but becomes non trivial if you need to * structure than just during structure check. Usually just save some few bytes, but becomes non trivial if you need to
* record too much stuff. * record too much stuff.
* * <p>
* You will have to reset the context yourself though. The API can't guess when the old context becomes invalid. * You will have to reset the context yourself though. The API can't guess when the old context becomes invalid.
*
* @param <CTX> the temporary state context * @param <CTX> the temporary state context
*/ */
public interface IWithExtendedContext<CTX> { public interface IWithExtendedContext<CTX> {
@@ -6,33 +6,33 @@ import net.minecraft.world.World;
import java.util.function.Function; import java.util.function.Function;
class LazyStructureElement<T> implements IStructureElementDeferred<T> { class LazyStructureElement<T> implements IStructureElementDeferred<T> {
private Function<T, IStructureElement<T>> to; private Function<T, IStructureElement<T>> to;
private IStructureElement<T> elem; private IStructureElement<T> elem;
public LazyStructureElement(Function<T, IStructureElement<T>> to) { public LazyStructureElement(Function<T, IStructureElement<T>> to) {
this.to = to; this.to = to;
} }
private IStructureElement<T> get(T t) { private IStructureElement<T> get(T t) {
if (to != null) { if (to != null) {
elem = to.apply(t); elem = to.apply(t);
to = null; to = null;
} }
return elem; return elem;
} }
@Override @Override
public boolean check(T t, World world, int x, int y, int z) { public boolean check(T t, World world, int x, int y, int z) {
return get(t).check(t, world, x, y, z); return get(t).check(t, world, x, y, z);
} }
@Override @Override
public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) {
return get(t).placeBlock(t, world, x, y, z, trigger); return get(t).placeBlock(t, world, x, y, z, trigger);
} }
@Override @Override
public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) {
return get(t).spawnHint(t, world, x, y, z, trigger); return get(t).spawnHint(t, world, x, y, z, trigger);
} }
} }
@@ -9,193 +9,193 @@ import static com.gtnewhorizon.structurelib.StructureLib.DEBUG_MODE;
import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; import static com.gtnewhorizon.structurelib.structure.StructureUtility.*;
public class StructureDefinition<T> implements IStructureDefinition<T> { public class StructureDefinition<T> implements IStructureDefinition<T> {
private final Map<Character, IStructureElement<T>> elements; private final Map<Character, IStructureElement<T>> elements;
private final Map<String, String> shapes; private final Map<String, String> shapes;
private final Map<String, IStructureElement<T>[]> structures; private final Map<String, IStructureElement<T>[]> structures;
public static <B> Builder<B> builder() { public static <B> Builder<B> builder() {
return new Builder<>(); return new Builder<>();
} }
private StructureDefinition( private StructureDefinition(
Map<Character, IStructureElement<T>> elements, Map<Character, IStructureElement<T>> elements,
Map<String, String> shapes, Map<String, String> shapes,
Map<String, IStructureElement<T>[]> structures) { Map<String, IStructureElement<T>[]> structures) {
this.elements = elements; this.elements = elements;
this.shapes = shapes; this.shapes = shapes;
this.structures = structures; this.structures = structures;
} }
public static class Builder<T> { public static class Builder<T> {
private static final char A = '\uA000'; private static final char A = '\uA000';
private static final char B = '\uB000'; private static final char B = '\uB000';
private static final char C = '\uC000'; private static final char C = '\uC000';
private char d = '\uD000'; private char d = '\uD000';
private final Map<Vec3Impl, Character> navigates; private final Map<Vec3Impl, Character> navigates;
private final Map<Character, IStructureElement<T>> elements; private final Map<Character, IStructureElement<T>> elements;
private final Map<String, String> shapes; private final Map<String, String> shapes;
private Builder() { private Builder() {
navigates = new HashMap<>(); navigates = new HashMap<>();
elements = new HashMap<>(); elements = new HashMap<>();
shapes = new HashMap<>(); shapes = new HashMap<>();
} }
public Map<Character, IStructureElement<T>> getElements() { public Map<Character, IStructureElement<T>> getElements() {
return elements; return elements;
} }
public Map<String, String> getShapes() { public Map<String, String> getShapes() {
return shapes; return shapes;
} }
/** /**
* Adds shape * Adds shape
* + is anything but air * + is anything but air
* - is air checks * - is air checks
* space bar is skip * space bar is skip
* ~ is also skip (but marks controller position, optional and logically it is a space...) * ~ is also skip (but marks controller position, optional and logically it is a space...)
* rest needs to be defined * rest needs to be defined
* <p> * <p>
* next char is next block(a) * next char is next block(a)
* next string is next line(b) * next string is next line(b)
* next string[] is next slice(c) * next string[] is next slice(c)
* <p> * <p>
* char A000-FFFF range is reserved for generated skips * char A000-FFFF range is reserved for generated skips
* *
* @param name unlocalized/code name * @param name unlocalized/code name
* @param structurePiece generated or written struct - DO NOT STORE IT ANYWHERE, or at least set them to null afterwards * @param structurePiece generated or written struct - DO NOT STORE IT ANYWHERE, or at least set them to null afterwards
* @return this builder * @return this builder
*/ */
public Builder<T> addShape(String name, String[][] structurePiece) { public Builder<T> addShape(String name, String[][] structurePiece) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
if (structurePiece.length > 0) { if (structurePiece.length > 0) {
for (String[] strings : structurePiece) { for (String[] strings : structurePiece) {
if (strings.length > 0) { if (strings.length > 0) {
for (String string : strings) { for (String string : strings) {
builder.append(string).append(B); builder.append(string).append(B);
} }
builder.setLength(builder.length() - 1); builder.setLength(builder.length() - 1);
} }
builder.append(C); builder.append(C);
} }
builder.setLength(builder.length() - 1); builder.setLength(builder.length() - 1);
} }
int a = 0, b = 0, c = 0; int a = 0, b = 0, c = 0;
for (int i = 0; i < builder.length(); i++) { for (int i = 0; i < builder.length(); i++) {
char ch = builder.charAt(i); char ch = builder.charAt(i);
if (ch == ' ' || ch == '~') { if (ch == ' ' || ch == '~') {
builder.setCharAt(i, A); builder.setCharAt(i, A);
ch = A; ch = A;
} }
if (ch == A) { if (ch == A) {
a++; a++;
} else if (ch == B) { } else if (ch == B) {
a = 0; a = 0;
b++; b++;
} else if (ch == C) { } else if (ch == C) {
a = 0; a = 0;
b = 0; b = 0;
c++; c++;
} else if (a != 0 || b != 0 || c != 0) { } else if (a != 0 || b != 0 || c != 0) {
Vec3Impl vec3 = new Vec3Impl(a, b, c); Vec3Impl vec3 = new Vec3Impl(a, b, c);
Character navigate = navigates.get(vec3); Character navigate = navigates.get(vec3);
if (navigate == null) { if (navigate == null) {
navigate = d++; navigate = d++;
navigates.put(vec3, navigate); navigates.put(vec3, navigate);
addElement(navigate, step(vec3)); addElement(navigate, step(vec3));
} }
builder.setCharAt(i - 1, navigate); builder.setCharAt(i - 1, navigate);
a = 0; a = 0;
b = 0; b = 0;
c = 0; c = 0;
} }
} }
String built = builder.toString().replaceAll("[\\uA000\\uB000\\uC000]", ""); String built = builder.toString().replaceAll("[\\uA000\\uB000\\uC000]", "");
if (built.contains("+")) { if (built.contains("+")) {
addElement('+', notAir()); addElement('+', notAir());
} }
if (built.contains("-")) { if (built.contains("-")) {
addElement('-', isAir()); addElement('-', isAir());
} }
shapes.put(name, built); shapes.put(name, built);
return this; return this;
} }
public Builder<T> addElement(Character name, IStructureElement<T> structurePiece) { public Builder<T> addElement(Character name, IStructureElement<T> structurePiece) {
elements.putIfAbsent(name, structurePiece); elements.putIfAbsent(name, structurePiece);
return this; return this;
} }
public IStructureDefinition<T> build() { public IStructureDefinition<T> build() {
Map<String, IStructureElement<T>[]> structures = compileStructureMap(); Map<String, IStructureElement<T>[]> structures = compileStructureMap();
if (DEBUG_MODE) { if (DEBUG_MODE) {
return new StructureDefinition<>(new HashMap<>(elements), new HashMap<>(shapes), structures); return new StructureDefinition<>(new HashMap<>(elements), new HashMap<>(shapes), structures);
} else { } else {
return structures::get; return structures::get;
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Map<String, IStructureElement<T>[]> compileElementSetMap() { private Map<String, IStructureElement<T>[]> compileElementSetMap() {
Set<Integer> missing = findMissing(); Set<Integer> missing = findMissing();
if (missing.isEmpty()) { if (missing.isEmpty()) {
return shapes.entrySet().stream() return shapes.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, .collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().chars() e -> e.getValue().chars()
.mapToObj(c -> (char) c) .mapToObj(c -> (char) c)
.distinct() .distinct()
.map(elements::get) .map(elements::get)
.toArray(IStructureElement[]::new) .toArray(IStructureElement[]::new)
)); ));
} else { } else {
throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " + throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " +
Arrays.toString(missing.toArray())); Arrays.toString(missing.toArray()));
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Map<String, IStructureElement<T>[]> compileStructureMap() { private Map<String, IStructureElement<T>[]> compileStructureMap() {
Set<Integer> missing = findMissing(); Set<Integer> missing = findMissing();
if (missing.isEmpty()) { if (missing.isEmpty()) {
return shapes.entrySet().stream() return shapes.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, .collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().chars().mapToObj(c -> elements.get((char) c)).toArray(IStructureElement[]::new) e -> e.getValue().chars().mapToObj(c -> elements.get((char) c)).toArray(IStructureElement[]::new)
)); ));
} else { } else {
throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " + throw new RuntimeException("Missing Structure Element bindings for (chars as integers): " +
Arrays.toString(missing.toArray())); Arrays.toString(missing.toArray()));
} }
} }
private Set<Integer> findMissing() { private Set<Integer> findMissing() {
return shapes.values().stream() return shapes.values().stream()
.flatMapToInt(CharSequence::chars) .flatMapToInt(CharSequence::chars)
.filter(i -> !elements.containsKey((char) i)) .filter(i -> !elements.containsKey((char) i))
.boxed() .boxed()
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
} }
public Map<Character, IStructureElement<T>> getElements() { public Map<Character, IStructureElement<T>> getElements() {
return elements; return elements;
} }
public Map<String, String> getShapes() { public Map<String, String> getShapes() {
return shapes; return shapes;
} }
public Map<String, IStructureElement<T>[]> getStructures() { public Map<String, IStructureElement<T>[]> getStructures() {
return structures; return structures;
} }
@Override @Override
public IStructureElement<T>[] getStructureFor(String name) { public IStructureElement<T>[] getStructureFor(String name) {
IStructureElement<T>[] elements = structures.get(name); IStructureElement<T>[] elements = structures.get(name);
if (elements == null) if (elements == null)
throw new NoSuchElementException(name); throw new NoSuchElementException(name);
return elements; return elements;
} }
} }
File diff suppressed because it is too large. Load diff
@@ -4,12 +4,12 @@ package com.gtnewhorizon.structurelib.structure.adders;
import net.minecraft.block.Block; import net.minecraft.block.Block;
public interface IBlockAdder<T> { public interface IBlockAdder<T> {
/** /**
* Callback on block added, needs to check if block is valid (and add it) * Callback on block added, needs to check if block is valid (and add it)
* *
* @param block block attempted to add * @param block block attempted to add
* @param meta meta of block attempted to add * @param meta meta of block attempted to add
* @return is structure still valid * @return is structure still valid
*/ */
boolean apply(T t, Block block, int meta); boolean apply(T t, Block block, int meta);
} }
@@ -3,11 +3,11 @@ package com.gtnewhorizon.structurelib.structure.adders;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
public interface ITileAdder<T> { public interface ITileAdder<T> {
/** /**
* Callback to add hatch, needs to check if tile is valid (and add it) * Callback to add hatch, needs to check if tile is valid (and add it)
* *
* @param tileEntity tile * @param tileEntity tile
* @return managed to add hatch (structure still valid) * @return managed to add hatch (structure still valid)
*/ */
boolean apply(T t, TileEntity tileEntity); boolean apply(T t, TileEntity tileEntity);
} }
@@ -23,11 +23,15 @@ public class Vec3Impl implements Comparable<Vec3Impl> {
* Gets the coordinate. * Gets the coordinate.
*/ */
public int get(int index) { public int get(int index) {
switch (index){ switch (index) {
case 0: return val0; case 0:
case 1: return val1; return val0;
case 2: return val2; case 1:
default: return 0; return val1;
case 2:
return val2;
default:
return 0;
} }
} }
@@ -64,17 +68,17 @@ public class Vec3Impl implements Comparable<Vec3Impl> {
return new Vec3Impl(val0 - pos.val0, val1 - pos.val1, val2 - pos.val2); return new Vec3Impl(val0 - pos.val0, val1 - pos.val1, val2 - pos.val2);
} }
public Vec3Impl add(int pos0,int pos1,int pos2) { public Vec3Impl add(int pos0, int pos1, int pos2) {
return new Vec3Impl(val0 + pos0, val1 + pos1, val2 + pos2); return new Vec3Impl(val0 + pos0, val1 + pos1, val2 + pos2);
} }
public Vec3Impl sub(int pos0,int pos1,int pos2) { public Vec3Impl sub(int pos0, int pos1, int pos2) {
return new Vec3Impl(val0 - pos0, val1 - pos1, val2 - pos2); return new Vec3Impl(val0 - pos0, val1 - pos1, val2 - pos2);
} }
public Vec3Impl crossProduct(Vec3Impl vec) { public Vec3Impl crossProduct(Vec3Impl vec) {
return new Vec3Impl(val1 * vec.val2 - val2 * vec.val1, val2 * vec.val0 - val0 * vec.val2, return new Vec3Impl(val1 * vec.val2 - val2 * vec.val1, val2 * vec.val0 - val0 * vec.val2,
val0 * vec.val1 - val1 * vec.val0); val0 * vec.val1 - val1 * vec.val0);
} }
public boolean withinDistance(Vec3Impl to, double distance) { public boolean withinDistance(Vec3Impl to, double distance) {
@@ -95,17 +99,17 @@ public class Vec3Impl implements Comparable<Vec3Impl> {
public double distanceSq(double x, double y, double z, boolean useCenter) { public double distanceSq(double x, double y, double z, boolean useCenter) {
double d0 = useCenter ? 0.5D : 0.0D; double d0 = useCenter ? 0.5D : 0.0D;
double d1 = (double)val0 + d0 - x; double d1 = (double) val0 + d0 - x;
double d2 = (double)val1 + d0 - y; double d2 = (double) val1 + d0 - y;
double d3 = (double)val2 + d0 - z; double d3 = (double) val2 + d0 - z;
return d1 * d1 + d2 * d2 + d3 * d3; return d1 * d1 + d2 * d2 + d3 * d3;
} }
public int manhattanDistance(Vec3Impl to) { public int manhattanDistance(Vec3Impl to) {
float f = (float)Math.abs(to.val0 - val0); float f = (float) Math.abs(to.val0 - val0);
float f1 = (float)Math.abs(to.val1 - val1); float f1 = (float) Math.abs(to.val1 - val1);
float f2 = (float)Math.abs(to.val2 - val2); float f2 = (float) Math.abs(to.val2 - val2);
return (int)(f + f1 + f2); return (int) (f + f1 + f2);
} }
@Override @Override
@@ -114,14 +118,14 @@ public class Vec3Impl implements Comparable<Vec3Impl> {
} }
public Vec3Impl abs() { public Vec3Impl abs() {
return new Vec3Impl(Math.abs(val0),Math.abs(val1),Math.abs(val2)); return new Vec3Impl(Math.abs(val0), Math.abs(val1), Math.abs(val2));
} }
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) { if (this == o) {
return true; return true;
} else if (o instanceof Vec3Impl) { } else if (o instanceof Vec3Impl) {
Vec3Impl vec3i = (Vec3Impl)o; Vec3Impl vec3i = (Vec3Impl) o;
return val0 == vec3i.val0 && val1 == vec3i.val1 && val2 == vec3i.val2; return val0 == vec3i.val0 && val1 == vec3i.val1 && val2 == vec3i.val2;
} }
return false; return false;
@@ -130,4 +134,4 @@ public class Vec3Impl implements Comparable<Vec3Impl> {
public int hashCode() { public int hashCode() {
return (val1 + val2 * 31) * 31 + val0; return (val1 + val2 * 31) * 31 + val0;
} }
} }
@@ -43,10 +43,10 @@ public class XSTR extends Random {
private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53) private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24) private static final float FLOAT_UNIT = 0x1.0p-24f; // 1.0f / (1 << 24)
private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L); private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
public static final XSTR XSTR_INSTANCE=new XSTR(){ public static final XSTR XSTR_INSTANCE = new XSTR() {
@Override @Override
public synchronized void setSeed(long seed) { public synchronized void setSeed(long seed) {
if(!Thread.currentThread().getStackTrace()[2].getClassName().equals(Random.class.getName())) { if (!Thread.currentThread().getStackTrace()[2].getClassName().equals(Random.class.getName())) {
throw new NoSuchMethodError("This is meant to be shared!, leave seed state alone!"); throw new NoSuchMethodError("This is meant to be shared!, leave seed state alone!");
} }
} }
@@ -275,4 +275,4 @@ public class XSTR extends Random {
} }
} }
} }
} }
@@ -22,10 +22,10 @@ item.structurelib.frontRotationTool.desc.2=which allows structure rotation.
item.structurelib.constructableTrigger.name=Multiblock Structure Hologram Projector item.structurelib.constructableTrigger.name=Multiblock Structure Hologram Projector
item.structurelib.constructableTrigger.desc.0=Triggers Constructable Interface item.structurelib.constructableTrigger.desc.0=Triggers Constructable Interface
item.structurelib.constructableTrigger.desc.1=Shows multiblock construction details, item.structurelib.constructableTrigger.desc.1=Shows multiblock construction schematic,
item.structurelib.constructableTrigger.desc.2=just Use on a multiblock controller. item.structurelib.constructableTrigger.desc.2=use on the multiblock controller.
item.structurelib.constructableTrigger.desc.3=(Sneak Use in creative to build) item.structurelib.constructableTrigger.desc.3=(Sneak use on controller in creative to build)
item.structurelib.constructableTrigger.desc.4=Quantity affects tier/mode/type item.structurelib.constructableTrigger.desc.4=Quantity of schematics in item stack affects tier/mode/type
structurelib.blockhint.desc.0=Helps while building structurelib.blockhint.desc.0=Helps while building
structurelib.blockhint.0.name=Hint 1 dot structurelib.blockhint.0.name=Hint 1 dot
@@ -51,6 +51,103 @@ structurelib.blockhint.15.name=Hint error
structurelib.blockhint.desc.5=ERROR, what did u expect? structurelib.blockhint.desc.5=ERROR, what did u expect?
itemGroup.structurelib=StructureLib itemGroup.structurelib=StructureLib
structurelib.facing.0=down normal none
structurelib.facing.1=down normal horizontal
structurelib.facing.2=down normal vertical
structurelib.facing.3=down normal both
structurelib.facing.4=down clockwise none
structurelib.facing.5=down clockwise horizontal
structurelib.facing.6=down clockwise vertical
structurelib.facing.7=down clockwise both
structurelib.facing.8=down upside down
structurelib.facing.9=down upside down
structurelib.facing.10=down upside down
structurelib.facing.11=down upside down
structurelib.facing.12=down counter clockwise
structurelib.facing.13=down counter clockwise
structurelib.facing.14=down counter clockwise
structurelib.facing.15=down counter clockwise
structurelib.facing.16=up normal none
structurelib.facing.17=up normal horizontal
structurelib.facing.18=up normal vertical
structurelib.facing.19=up normal both
structurelib.facing.20=up clockwise none
structurelib.facing.21=up clockwise horizontal
structurelib.facing.22=up clockwise vertical
structurelib.facing.23=up clockwise both
structurelib.facing.24=up upside down
structurelib.facing.25=up upside down
structurelib.facing.26=up upside down
structurelib.facing.27=up upside down
structurelib.facing.28=up counter clockwise
structurelib.facing.29=up counter clockwise
structurelib.facing.30=up counter clockwise
structurelib.facing.31=up counter clockwise
structurelib.facing.32=north normal none
structurelib.facing.33=north normal horizontal
structurelib.facing.34=north normal vertical
structurelib.facing.35=north normal both
structurelib.facing.36=north clockwise none
structurelib.facing.37=north clockwise horizontal
structurelib.facing.38=north clockwise vertical
structurelib.facing.39=north clockwise both
structurelib.facing.40=north upside down
structurelib.facing.41=north upside down
structurelib.facing.42=north upside down
structurelib.facing.43=north upside down
structurelib.facing.44=north counter clockwise
structurelib.facing.45=north counter clockwise
structurelib.facing.46=north counter clockwise
structurelib.facing.47=north counter clockwise
structurelib.facing.48=south normal none
structurelib.facing.49=south normal horizontal
structurelib.facing.50=south normal vertical
structurelib.facing.51=south normal both
structurelib.facing.52=south clockwise none
structurelib.facing.53=south clockwise horizontal
structurelib.facing.54=south clockwise vertical
structurelib.facing.55=south clockwise both
structurelib.facing.56=south upside down
structurelib.facing.57=south upside down
structurelib.facing.58=south upside down
structurelib.facing.59=south upside down
structurelib.facing.60=south counter clockwise
structurelib.facing.61=south counter clockwise
structurelib.facing.62=south counter clockwise
structurelib.facing.63=south counter clockwise
structurelib.facing.64=west normal none
structurelib.facing.65=west normal horizontal
structurelib.facing.66=west normal vertical
structurelib.facing.67=west normal both
structurelib.facing.68=west clockwise none
structurelib.facing.69=west clockwise horizontal
structurelib.facing.70=west clockwise vertical
structurelib.facing.71=west clockwise both
structurelib.facing.72=west upside down
structurelib.facing.73=west upside down
structurelib.facing.74=west upside down
structurelib.facing.75=west upside down
structurelib.facing.76=west counter clockwise
structurelib.facing.77=west counter clockwise
structurelib.facing.78=west counter clockwise
structurelib.facing.79=west counter clockwise
structurelib.facing.80=east normal none
structurelib.facing.81=east normal horizontal
structurelib.facing.82=east normal vertical
structurelib.facing.83=east normal both
structurelib.facing.84=east clockwise none
structurelib.facing.85=east clockwise horizontal
structurelib.facing.86=east clockwise vertical
structurelib.facing.87=east clockwise both
structurelib.facing.88=east upside down
structurelib.facing.89=east upside down
structurelib.facing.90=east upside down
structurelib.facing.91=east upside down
structurelib.facing.92=east counter clockwise
structurelib.facing.93=east counter clockwise
structurelib.facing.94=east counter clockwise
structurelib.facing.95=east counter clockwise
structurelib.config.client=Client Side Configurations structurelib.config.client=Client Side Configurations
structurelib.config.client.tooltip=Configurations that only changes how the game looks like, but not how it functions. structurelib.config.client.tooltip=Configurations that only changes how the game looks like, but not how it functions.
structurelib.config.client.hologram=Hologram Configurations structurelib.config.client.hologram=Hologram Configurations
@@ -23,7 +23,7 @@ item.structurelib.frontRotationTool.desc.2=多方块主机一起旋转/翻转。
item.structurelib.constructableTrigger.name=多方块结构全息投影仪 item.structurelib.constructableTrigger.name=多方块结构全息投影仪
item.structurelib.constructableTrigger.desc.0=可以显示多方块机器的结构 item.structurelib.constructableTrigger.desc.0=可以显示多方块机器的结构
item.structurelib.constructableTrigger.desc.1=只能在多方块主机上使用,将会显示机器 item.structurelib.constructableTrigger.desc.1=只能在多方块主机上使用,将会显示机器
item.structurelib.constructableTrigger.desc.2=结构的细节。 (译者注:请搭高使用) item.structurelib.constructableTrigger.desc.2=结构的示意图。 (译者注:请搭高使用)
item.structurelib.constructableTrigger.desc.3= (创造模式下潜行右键可以直接完成搭建) item.structurelib.constructableTrigger.desc.3= (创造模式下潜行右键可以直接完成搭建)
item.structurelib.constructableTrigger.desc.4=此物品堆叠数量会影响显示的机器等级/模式/类型 item.structurelib.constructableTrigger.desc.4=此物品堆叠数量会影响显示的机器等级/模式/类型
@@ -51,6 +51,103 @@ structurelib.blockhint.15.name=提示方块:错误
structurelib.blockhint.desc.5=ERROR,你想要做什么? structurelib.blockhint.desc.5=ERROR,你想要做什么?
itemGroup.structurelib=StructureLib itemGroup.structurelib=StructureLib
structurelib.facing.0=面朝下方
structurelib.facing.1=面朝下方,并水平翻转
structurelib.facing.2=面朝下方,并垂直翻转
structurelib.facing.3=面朝下方,并旋转180度
structurelib.facing.4=面朝下方,并顺时针旋转90度
structurelib.facing.5=面朝下方,顺时针旋转90度并水平翻转
structurelib.facing.6=面朝下方,顺时针旋转90度并垂直翻转
structurelib.facing.7=面朝下方,并逆时针旋转90度
structurelib.facing.8=面朝下方,并旋转180度
structurelib.facing.9=面朝下方,并垂直翻转
structurelib.facing.10=面朝下方,并水平翻转
structurelib.facing.11=面朝下方
structurelib.facing.12=面朝下方,并逆时针旋转90度
structurelib.facing.13=面朝下方,逆时针旋转90度并水平翻转
structurelib.facing.14=面朝下方,逆时针旋转90度并垂直翻转
structurelib.facing.15=面朝下方,并顺时针旋转90度
structurelib.facing.16=面朝上方
structurelib.facing.17=面朝上方,并水平翻转
structurelib.facing.18=面朝上方,并垂直翻转
structurelib.facing.19=面朝上方,并旋转180度
structurelib.facing.20=面朝上方,并顺时针旋转90度
structurelib.facing.21=面朝上方,顺时针旋转90度并水平翻转
structurelib.facing.22=面朝上方,顺时针旋转90度并垂直翻转
structurelib.facing.23=面朝上方,并逆时针旋转90度
structurelib.facing.24=面朝上方,并旋转180度
structurelib.facing.25=面朝上方,并垂直翻转
structurelib.facing.26=面朝上方,并水平翻转
structurelib.facing.27=面朝上方
structurelib.facing.28=面朝上方,并逆时针旋转90度
structurelib.facing.29=面朝上方,逆时针旋转90度并水平翻转
structurelib.facing.30=面朝上方,逆时针旋转90度并垂直翻转
structurelib.facing.31=面朝上方,并顺时针旋转90度
structurelib.facing.32=面朝北方
structurelib.facing.33=面朝北方,并水平翻转
structurelib.facing.34=面朝北方,并垂直翻转
structurelib.facing.35=面朝北方,并旋转180度
structurelib.facing.36=面朝北方,并顺时针旋转90度
structurelib.facing.37=面朝北方,顺时针旋转90度并水平翻转
structurelib.facing.38=面朝北方,顺时针旋转90度并垂直翻转
structurelib.facing.39=面朝北方,并逆时针旋转90度
structurelib.facing.40=面朝北方,并旋转180度
structurelib.facing.41=面朝北方,并垂直翻转
structurelib.facing.42=面朝北方,并水平翻转
structurelib.facing.43=面朝北方
structurelib.facing.44=面朝北方,并逆时针旋转90度
structurelib.facing.45=面朝北方,逆时针旋转90度并水平翻转
structurelib.facing.46=面朝北方,逆时针旋转90度并垂直翻转
structurelib.facing.47=面朝北方,并顺时针旋转90度
structurelib.facing.48=面朝南方
structurelib.facing.49=面朝南方,并水平翻转
structurelib.facing.50=面朝南方,并垂直翻转
structurelib.facing.51=面朝南方,并旋转180度
structurelib.facing.52=面朝南方,并顺时针旋转90度
structurelib.facing.53=面朝南方,顺时针旋转90度并水平翻转
structurelib.facing.54=面朝南方,顺时针旋转90度并垂直翻转
structurelib.facing.55=面朝南方,并逆时针旋转90度
structurelib.facing.56=面朝南方,并旋转180度
structurelib.facing.57=面朝南方,并垂直翻转
structurelib.facing.58=面朝南方,并水平翻转
structurelib.facing.59=面朝南方
structurelib.facing.60=面朝南方,并逆时针旋转90度
structurelib.facing.61=面朝南方,逆时针旋转90度并水平翻转
structurelib.facing.62=面朝南方,逆时针旋转90度并垂直翻转
structurelib.facing.63=面朝南方,并顺时针旋转90度
structurelib.facing.64=面朝西方
structurelib.facing.65=面朝西方,并水平翻转
structurelib.facing.66=面朝西方,并垂直翻转
structurelib.facing.67=面朝西方,并旋转180度
structurelib.facing.68=面朝西方,并顺时针旋转90度
structurelib.facing.69=面朝西方,顺时针旋转90度并水平翻转
structurelib.facing.70=面朝西方,顺时针旋转90度并垂直翻转
structurelib.facing.71=面朝西方,并逆时针旋转90度
structurelib.facing.72=面朝西方,并旋转180度
structurelib.facing.73=面朝西方,并垂直翻转
structurelib.facing.74=面朝西方,并水平翻转
structurelib.facing.75=面朝西方
structurelib.facing.76=面朝西方,并逆时针旋转90度
structurelib.facing.77=面朝西方,逆时针旋转90度并水平翻转
structurelib.facing.78=面朝西方,逆时针旋转90度并垂直翻转
structurelib.facing.79=面朝西方,并顺时针旋转90度
structurelib.facing.80=面朝东方
structurelib.facing.81=面朝东方,并水平翻转
structurelib.facing.82=面朝东方,并垂直翻转
structurelib.facing.83=面朝东方,并旋转180度
structurelib.facing.84=面朝东方,并顺时针旋转90度
structurelib.facing.85=面朝东方,顺时针旋转90度并水平翻转
structurelib.facing.86=面朝东方,顺时针旋转90度并垂直翻转
structurelib.facing.87=面朝东方,并逆时针旋转90度
structurelib.facing.88=面朝东方,并旋转180度
structurelib.facing.89=面朝东方,并垂直翻转
structurelib.facing.90=面朝东方,并水平翻转
structurelib.facing.91=面朝东方
structurelib.facing.92=面朝东方,并逆时针旋转90度
structurelib.facing.93=面朝东方,逆时针旋转90度并水平翻转
structurelib.facing.94=面朝东方,逆时针旋转90度并垂直翻转
structurelib.facing.95=面朝东方,并顺时针旋转90度
structurelib.config.client=客户端-配置 structurelib.config.client=客户端-配置
structurelib.config.client.tooltip=修改此配置只会改变游戏中的显示效果,而不会改变实际工作模式。 structurelib.config.client.tooltip=修改此配置只会改变游戏中的显示效果,而不会改变实际工作模式。
structurelib.config.client.hologram=全息投影仪-配置 structurelib.config.client.hologram=全息投影仪-配置